vector

一、vector:

1、在库中的一些表达vector底层维护了一段动态的连续空间,随着元素的不断插入,vector的内部机制会自
动检测,决定是否需要进行扩容以容纳新元素。三步操作:开辟新空间,拷贝元素,释放旧空间。

 

(1)构造,没有传任何参数,表示一个顺序表

explicit vector ( const Allocator& = Allocator() );

(2)构造:向顺序表中存放n个值为value的元素

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );

(3)构造first到last一个前闭后开的区间,用区间里的元素构造一个vector

 

template <class InputIterator>
         vector ( InputIterator first, InputIterator last, const Allocator& = Allocator() );

 

(4)拷贝构造

vector ( const vector<T,Allocator>& x );

(5)size:返回有效元素的个数

 

(6)resize:第一个参数表示把当前有效元素的位置改到sz这么多,sz可能比顺序表中有效元素少,也可能比顺序表中有效元素大(a、大于size,但是小于容量,不需要改变空间,多出来的元素用c填充;b、大于容量,则需要重新开辟空间,把原空间的内容拷贝过来,多出来的进行填充,顺序表里面的指针指向新空间。)。可能进行增容,改变元素的个数。

void resize ( size_type sz, T c = T() );

(7)reserve:预留空间只改变大小,不改变元素的个数

void reserve ( size_type n );

 

(8)operator[]的重载:给定一个下标,访问任意空间的元素,但是不能超过有效元素的个数

      reference operator[] ( size_type n );
const_reference operator[] ( size_type n ) const;

 

at:同operator的方法(成对的重载)

const_reference at ( size_type n ) const;
      reference at ( size_type n );

 

 

 

(9)front:第一个元素,也是成对的重载

 

返回第一个元素的引用:

reference front ( );

返回const类型的引用

const_reference front ( ) const;

(10)back:

   reference back ( );
const_reference back ( ) const;

注意与end区分,end返回的是size位置处的地址,和begin标记一块左闭右开的区间

 

(11)assign:赋值

 

push_back:尾插

 

pop_back:尾删

 

insert:任意位置的插入

 

erase:任意位置的删除

 

swap:交换两个顺序表中的内容

void swap ( vector<T,Allocator>& vec );

clear:清空

begin:指向第一个元素所在的位置

end:指向最后一个元素所在的位置,相当于size所在的位置

rbegin:在end的位置

rend:在begin的位置

vector里面只有尾插没有头插,但是可以使用"对象名1.insert(对象名1.begin(),0)"来代替头插。

只要能引起vector底层空间改变的东西:插入可能会增容,就可能需要给迭代器重新赋值,否则就可能会失效,(迭代器在底层关联的空间已经释放了。)。删除时可能会导致迭代器出现问题,空间存在,但是空间里的元素变成无意义的元素。

vector的使用场景:对任意位置的插入和删除操作比较少的情况。

(2)用库里面提供的vector写一段代码:

# include<assert.h>
# include<malloc.h>
# include<stdlib.h>
# include<iostream>
# include<vector>
using namespace std;
void Testvector()
{
	vector<int> v1;//构造整型的v1//vector必须加标准命名空间,方法同第一篇c++博客
	vector<int> v2(10, 5);//构造10个元素5
	//构造一个数组(左闭右开的区间)
	int arra[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	vector<int> v3(arra, arra + sizeof(arra) / sizeof(arra[0]));
	cout << v3.size() << endl;
	cout << v3.capacity() << endl;
	//按下标的方式打印
	for (size_t i = 0; i < v3.size(); ++i)
		cout << v3[i] << " ";
	cout << endl;
	//内置类型进行打印
	vector<int>::iterator it = v3.begin();
	while (it != v3.end())//没有走到末尾的位置
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	v3.resize(5);
	cout << v3.size() << endl;
	cout << v3.capacity() << endl;
	for (size_t i = 0; i < v3.size(); ++i)
		cout << v3[i] << " ";

	v3.resize(20, 6);
	cout << v3.size() << endl;
	cout << v3.capacity() << endl;
	for (size_t i = 0; i < v3.size(); ++i)
		cout << v3[i] << " ";
}


int main()
{
	Testvector();
 	return 0;
}

 

 

 

 

(3)自己封装一个vector:

 

 

 

 

二、用c++封装一个带头节点的双向循环链表

 

 

尾插:

 

 

尾删

 

 

头插:

 

# include<iostream>
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
# include<assert.h>
using namespace std;
typedef int DataType;
struct ListNode
{
	ListNode *_pNext;
	ListNode *_pPre;
	DataType _data;
	//构造函数
	ListNode(const DataType& data = DataType())
		:_pNext(NULL)
		, _pPre(NULL)
		, _data(data)

	{

	}
};
class List
{
public:
	//构造函数,构造新的链表,只有一个头节点
	List()
	{
		_CreateHead();
	}
	//向链表中放n个值为data的节点
	List(size_t n, const DataType& data)
	{
		//构造头
		_CreateHead();
		for (size_t i = 0; i < n; ++i)
			PushBack(data);

	}
	//[first,last)
	List(DataType *first, DataType *last)
	{
		_CreateHead();
		while (first != last)
			PushBack(*first++);
	}
	//拷贝构造
	List(const List& l)
{
       _pHead = new Node();
        _pHead->_pNext = _pHead;
        _pHead->_pPre = _pHead;

        Node* pCur = L._pHead->_pNext;
        while (pCur != L._pHead)
        {
            this->PushBack(pCur->_data);
            pCur = pCur->_pNext;
        }
}
	//赋值
	List& operator=(const List& s)
{
        if (this != &s)
        {
            this->Clear();
            Node* pCur = s._pHead->_pNext;
            while (pCur != s._pHead)
            {
                this->PushBack(pCur->_data);
                pCur = pCur->_pNext;
            }
        }
        return *this;
}
	//析构函数
	~List()
	{
		Clear();//把链表中的有效元素清空,不清空头
		//释放头节点
		delete _pHead;
		_pHead = NULL;
	}
	//关于容量的操作
	//有效节点的个数
	size_t Size()const
	{
		//遍历一遍链表
		ListNode* pCur = _pHead->_pNext;
		size_t count = 0;
		//pCue朝后走,没有走到头的位置,则一圈没有结束
		while (pCur != _pHead)
		{
			count++;
			pCur = pCur->_pNext;
		}
		return count;
	}
	//判断链表是否为空
	bool Empty()const
	{
		return _pHead->_pNext == _pHead;
	}
	//
	void ReSize(size_t newSize, const DataType &data = DataType())
	{
		int gap = newSize - Size();
		if (gap > 0)//链表节点个数增多了
		{
			while (gap--)
				PushBack(data);
		}
		else
		{
			while (gap++)
				PopBack();
		}
	}
	关于元素访问的操作
	DataType& Front()
	{
		assert(!Empty());
		return _pHead->_pNext->_data;
	}
	const DataType& Front()const
	{
		assert(!Empty());
		return _pHead->_pNext->_data;
	}
	//最后一个节点数据
	DataType& Back()
	{
		assert(!Empty());
		return _pHead->_pPre->_data;
	}
	const DataType& Back()const
	{
		assert(!Empty());
		return _pHead->_pPre->_data;
	}
	修改链表中的节点
	//尾插
	void PushBack(const DataType& data)
	{
		ListNode* pNewNode = new ListNode(data);
		pNewNode->_pPre = _pHead->_pPre;
		pNewNode->_pNext = _pHead;
		_pHead->_pPre = pNewNode;
		pNewNode->_pPre->_pNext = pNewNode;
	}
	//尾删
	void PopBack()
	{
		if (!Empty())
			return;
		//标记要删除的节点
		ListNode* pDelNode = _pHead->_pPre;
		pDelNode->_pPre->_pNext = _pHead;
		_pHead->_pPre = pDelNode->_pPre;
		delete pDelNode;
	}
	//头插
	void PushFront(const DataType& data)
	{
		ListNode* pNewNode = new ListNode(data);
		pNewNode->_pNext = _pHead->_pNext;
		pNewNode->_pPre = _pHead;
		_pHead->_pNext = pNewNode;
		pNewNode->_pNext->_pPre = pNewNode;
	}
	//头删
	void PopFront()
	{
		if (Empty())
			return;
		ListNode* pDelNode = _pHead->_pNext;
		_pHead->_pNext = pDelNode->_pNext;
		pDelNode->_pNext->_pPre = _pHead;
		delete pDelNode;
	}
	//任意位置的插入
	ListNode* Insert(ListNode* pos, const DataType& data)
	{
		ListNode* pNewNode = new ListNode(data);
		pNewNode->_pNext = pos;
		pNewNode->_pPre = pos->_pPre;
		pNewNode->_pPre->_pNext = pNewNode;
		//pos->_pPre = pNewNode;
		pNewNode->_pNext->_pPre = pNewNode;
		return pNewNode;
	}
	//任意位置的删除
	ListNode* Erase(ListNode* pos)
	{
		if (NULL==pos || pos == _pHead)
			return NULL;
		ListNode* ret = pos->_pNext;
		pos->_pPre->_pNext = pos->_pNext;
		pos->_pNext->_pPre = pos->_pPre;
		delete pos;
		return ret;//返回删除位置的下一个位置的元素
	}
	void Clear()
	{
		ListNode* pCur = _pHead->_pNext;
		while (pCur != _pHead)
		{
			pCur=Erase(pCur);
		}
	}
private:
	void _CreateHead()
	{
		//空链表的next域和pre域都指向自己
		_pHead = new ListNode;
		_pHead->_pNext = _pHead;
		_pHead->_pPre = _pHead;
	}
//打印函数
	friend ostream& operator<<(ostream& _cout, const List& l)
	{
		ListNode *pCur = l._pHead->_pNext;
		while (pCur!=l._pHead)
		{
			_cout << pCur->_data << " ";
			pCur = pCur->_pNext;
		}
		return _cout;
	}
private:
	//指向链表的头的指针
	ListNode* _pHead;
};

void TestList()
{
	List l1;
	List l2(10, 5);//10个元素5的链表
	cout << l2<< endl;
	int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	List l3(array, array + sizeof(array) / sizeof(array[0]));
	cout << l3.Size() << endl;
	cout << l3 << endl;
	cout << l3.Front() << endl;
	cout << l3.Back() << endl;
	l3.ReSize(5);
	cout << l3.Size() << endl;
	cout << l3 << endl;
	cout << l3.Front() << endl;
	cout << l3.Back() << endl;
	l3.ReSize(20);
	cout << l3.Size() << endl;
	cout << l3 << endl;
	cout << l3.Front() << endl;
	cout << l3.Back() << endl;
}

int main()
{
	TestList();
 	return 0;
}

 

 

 

 

 

 

用模板的方式实现一个双向循环链表

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<iostream>
using namespace std;

template<class T>
struct ListNode
{
	ListNode(const T& data = T())
	:_pPre(0)
	, _pNext(0)
	, _data(data)
	{

	}
	ListNode<T>* _pPre;
	ListNode<T>* _pNext;
	T _data;//值域
};
//List的迭代器
template<class T,class Ref,class Ptr>
struct ListIterator
{
	typedef ListNode<T> Node;
	typedef Node* PNode;
	typedef ListIterator<T, Ref, Ptr> Self;
public:
	//构造一个空的类型
	ListIterator()
		:_pNode(0)
	{}
	//用一个节点构造
	ListIterator(PNode pNode)
		:_pNode(pNode)
	{}
	//拷贝构造,类类型对象的引用
	ListIterator(const Selt& s)
		:_pNode(s._pNode)
	{
	}
	//重载
	Ref operator*()
	{
		return _pNode->_data;
	}
	Ptr operator->()
	{
		return &(_pNode->_data);
	}
	Seif& operator++():
	{
		_pNode = _pNode->_pNext;
		return *this;
	}
	Self operator++(int)
	{
		Self tmp(*this);
		_pNode = _pNode->_pNext;
		return tmp;
	}
	bool operator!=(const Self& s)
	{
		return _pNode != s._pNode;
	}
	bool operator==(const Self& s)
	{
		return _pNode == s._pNode;
	}
private:
	PNode _pNode;
};
template<class T>
class List
{
	typedef ListNode<T> Node;
	typedef Node* pNode;
public:
	typedef ListIterator<T,T&,T*> Iterator;
public:
	//构造函数
	//构造空的(带头节点)
	List()
	{
		_CreateHead();
	}
	//size个值为data的节点
	List(size_t size, const T& data = T())
	{
		_CreateHead();
		for (size_t i = 0; i < size; ++i)
			PushBack(data);
	}
	//[first,last)
	List(const T* first, const T* last)
	{
		_CreateHead();
		while (first != last){
			PushBack(*first);
			++first;
		}
	}
	//拷贝构造
	List(const List<T>& l);
	//赋值运算符的重载
	List<T>& operator=(const List<T>& l);
	~List()
	{
		Clear();
		delete _pHead;
		_pHead = NULL;
	}
	关于Iterator
	Iterator Begin()
	{
		return _pHead->_pNext;
	}
	Iterator End()
	{
		return _pHead;
	}
	///关于容量capacity的
	bool Empty()const
	{
		return _pHead->_pNext == _pHead;
	}
	size_t Size()const
	{
		pNode pCur = _pHead->_pNext;
		size_t count = 0;
		while (pCur != _pHead)
		{
			count++;
			pCur = pCur->_pNext;
		}
		return count;
	}
	void Resize(size_t newSize, const T& data = T())
	{
		size_t oldSize = Size();
		if (newSize > oldSize)
		{
			for (size_t i = oldSize; i < newSize; ++i)
				PushBack(data);
		}
		else
		{//有效元素个数减小了
			for (size_t i = oldSize; i >= newSize; --i)
				PopBack();
		}
	}
	/元素访问access,链表不支持随机访问
	T& Front()
	{
		return _pHead->_pNext->_data;
	}
	const T& Front()const
	{
		return _pHead->_pNext->_data;
	}
	T& Back()
	{
		return _pHead->_pNext->_data;
	}
	const T& Back()const
	{
		return _pHead->_pNext->_data;
	}
	modify
	void PushBack(const T& data)
	{
		pNode pNewNode = new Node(data);
		pNewNode->_pNext = _pHead;
		pNewNode->_pPre = _pHead->_pPre;
		pNewNode->_pPre->_pNext = pNewNode;
		_pHead->_pPre = pNewNode;
	}
	void PopBack()
	{
		pNode pDelNode = _pHead->_pPre;
		if (pDelNode)
		{
			pDelNode->_pPre->_pNext = _pHead;
			_pHead->_pPre = pDelNode->_pPre;
			delete pDelNode;
		}
	}
	void PushFront(const T& data)
	{
		pNode pNewNode = new Node(data);
		pNewNode->_pPre = _pHead;
		pNewNode->_pNext = _pHead->_pNext;
		_pHead->_pNext = pNewNode;
		pNewNode->_pNext->_pPre = pNewNode;
	}
	void PopFront()
	{
		pNode pDelNode = _pHead->_pNext;
		if (pDelNode){
			pDelNode->_pNext->_pPre = _pHead;
			_pHead->_pNext = pDelNode->_pNext;
			delete pDelNode;
		}
	}
	pNode Insert(pNode pos, const T& data)
	{
		assert(pos);
		pNode pNewNode = new Node(data);
		pNewNode->_pNext = pos;
		pNewNode->_pPre = pos->_pPre;
		pos->_pPre = pNewNode;
		pNewNode->_pPre->_pNext = pNewNode;
		return pNewNode;
	}
	pNode Erase(pNode pos)
	{
		assert(pos);
		pNode pRet = pos->_pNext;
		pos->_pPre->_pNext = pos->_pNext;
		pos->_pNext->_pPre = pos->_pPre;
		delete pos;
		return pRet;
	}
	//clear清理掉当前链表的节点
	void Clear()
	{
		pNode pDelNode = _pHead->_pNext;
		//头删的方式
		while (pDelNode != _pHead)
		{
			_pHead->_pNext = pDelNode->_pNext;
			delete pDelNode;
			pDelNode = _pHead->_pNext;
		}
		_pHead->_pNext = _pHead;
		_pHead->_pPre = _pHead;
	}
private:
	void _CreateHead()
	{
		_pHead = new Node;
		_pHead->_pNext = _pHead;
		_pHead->_pPre = _pHead;
	}
private:
	ListNode<T>* _pHead;
};

void TestList()
{
	List<int> l;
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	l.PushBack(5);
	List<int>::Iterator it = l.Begin();
	while (it != l.End())
	{
		cout << *it << " ";//it是一个节点,直接解引用是一个Node,链表的指针不能直接++,不连续。把指针进行封装
		//cout << it->_data << " ";
		++it;
	}
}

 

 

 

(2)库内的实现:

 

A、构造函数:

 

 

a、一个有效元素都没有为空:

explicit list ( const Allocator& = Allocator() );

b、向链表中放了n个值为value的元素,

explicit list ( size_type n, const T& value = T(), const Allocator& = Allocator() );

c、用一段区间构造链表

 

template < class InputIterator >
         list ( InputIterator first, InputIterator last, const Allocator& = Allocator() );

 

 

 

d、拷贝构造函数:

list ( const list<T,Allocator>& x );

B、empty:检测链表是否为空,为空为true;不为空返回false

 

C、返回链表中有效元素的个数

 

D、resize:改变链表中节点的个数,可能增多也可能减少

就不一一赘述了吐舌头

输入一个链表从尾到头打印单链表的值

法一:将链表中节点中的值全部保存在vector中,将vector逆序

#include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<iostream>
# include<vector>
using namespace std;
typedef int DataType;
typedef struct ListNode
{
	ListNode *_pNext;
	DataType data;
}*pListNode,ListNode;

 

class Solution{
public:
	vector<int> PrintListFromTailToHead(pListNode *pHead)
	{
		vector<int> v;
		ListNode *pCur = *pHead;
		while (pCur){
			v.push_back(pCur->data);
			pCur = pCur->_pNext;
		}
		reverse(v.begin(), v.end());
		return v;
	}
};

法2:递归实现

class Solution{
public:
	vector<int> PrintListFromTailToHead(ListNode *pHead)
	{
		vector<int> v;
		_PrintListFromTailToHead(pHead, v);
		return v;
	}
private:
	void _PrintListFromTailToHead(ListNode *pHead, vector<int> &v){
		if (pHead){
			_PrintListFromTailToHead(pHead->_pNext, v);
			v.push_back(pHead->data);
		}
	}
};

法3:用栈实现

# include<stack>
class Solution{
	vector<int> PrintFronTailToHead(pListNode *pHead){
		vector<int> ret;
		if (NULL == pHead){
			return ret;
		}
		stack<ListNode*> s;
		ListNode *pCur;
		while (pCur)
		{
			s.push(pCur);
			pCur = pCur->_pNext;
		}
		ret.resize(s.size());
		int index = 0;
		while (!s.empty()){
			ret[index++] = s.top()->data;
			s.pop();
		}
		return ret;
	}
};

 

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuruhua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值