C++ vector

vector的介绍及使用

1.1vector的介绍
1 .vector是表示可变大小数组的序列容器。
2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
6. 与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。
1.2vector的使用
vector的文档:http://www.cplusplus.com/reference/vector/vector/.
1.2.1vector的定义
在这里插入图片描述
1.2.2vector的使用
在这里插入图片描述
在这里插入图片描述
1.2.3vector的空间增长问题
在这里插入图片描述
resize只负责开辟空间,如果确定知道需要用多少空间,reverse可以缓解vector增容的代价问题
resize开辟空间的同时还会初始化,影响size。
1.2.3vector的增删查改
在这里插入图片描述
1.2.4vector的迭代器失效问题
迭代器的主要作用是让算法不用关心底层的数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如,vector的迭代器就是原生态指针T*。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成程序崩溃。
对于可能造成迭代器失效的操作有
1.会引起底层空间改变的操作都有可能造成迭代器失效,比如:resize,reverse,insert,push_back,assign等等。
2.指定元素的删除操作-earse
earse删除pos位置元素后,pos元素之后的元素会往前搬移,没有导致底层空间的改变,理论上迭代器不会失效,但是,如果pos刚好是最后一个元素,删完之后刚好是end的位置,而end位置是没有元素的,那么pos就失效了,因此删除vector上任意一个元素时,vs就认为该位置的迭代器失效了。
迭代器失效的解决方法:在使用之前,对迭代器重新赋值即可。
总结
vector的常用接口更多是插入与遍历,遍历最好用数组ret[i]的形式进行访问,因为vector里边没有对<<的重载,所以无法直接进行打印,用数组的方式会更为方便。

vector的模拟实现

namespace bit
{
	template<class _Ty>
	class vector
	{
	public:
		typedef _Ty* iterator;
		typedef const _Ty* const_iterator;
		typedef size_t size_type;
	public:
		vector() : _start(nullptr), _finish(nullptr),_end_of_storage(nullptr)
		{}
		vector(int n, const _Ty& value = _Ty())
			: _start(nullptr), _finish(nullptr),
			_end_of_storage(nullptr)
		{
			reserve(n);
			while(n--)
				push_back(value);
		}
		vector(const_iterator first, const_iterator last)
			: _start(nullptr), _finish(nullptr),
			_end_of_storage(nullptr)
		{
			reserve(last - first);
			while(first != last)
				push_back(*first++);
		}
		vector(const vector<_Ty> &v)
			 : _start(nullptr), _finish(nullptr),
			_end_of_storage(nullptr)
		{
			reserve(v.capacity());
			for(int i=0; i<v.size(); ++i)
				_start[i] = v[i];
			_finish = _start + v.size();
		}
		vector<_Ty>& operator=(const vector<_Ty> &v)
		{
			if(this != &v)
			{
				vector<_Ty> tmp = v;
				swap(tmp);
			}
			return *this;
		}
		~vector()
		{
			if(_start)
			{
				delete []_start;
				_start = _finish = _end_of_storage = nullptr;
			}
		}
	public:
		void push_back(const _Ty &x)
		{
			insert(end(), x);
		}
		void pop_back()
		{
			erase(end()-1);
		}
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
	public:
		_Ty& operator[](size_t pos)
		{
			return _start[pos];
		}
		const _Ty& operator[](size_t pos)const 
		{
			return _start[pos];
		}
		const _Ty& at(size_type pos) const
		{
			assert(pos>=0 && pos<size());
			return _start[pos];
		}
		_Ty& at(size_type pos)
		{
			assert(pos>=0 && pos<size());
			return _start[pos];
		}

	public:
		iterator insert(iterator pos, const _Ty& x)
		{
			if(_finish == _end_of_storage)
			{
				size_t old_n = pos - _start;
				size_t new_sz = capacity()==0 ? 1 : 2*capacity();
				reserve(new_sz);
				//重新更新迭代器 pos
				pos = _start + old_n;
			}

			iterator cur = end();
			while(cur != pos)
			{
				*cur = *(cur-1);
				cur--;
			}
			*cur = x;   //
			_finish++;
			return cur;
		}

		iterator erase(iterator pos)
		{
			assert(pos>=_start && pos<_finish);

			iterator cur = pos;
			while(pos < _finish)
			{
				*pos = *(pos+1);
				pos++;
			}
			--_finish;
			return cur;
		}

		void reserve(size_type n)
		{
			if(n > capacity())
			{
				size_t old_sz = size();
				_Ty *new_start = new _Ty[n];
				//memcpy(new_start, _start, sizeof(_Ty)*old_sz);
				for(int i=0; i<old_sz; ++i)
				{
					new_start[i] = _start[i];
				}
				delete []_start;

				_start = new_start;
				_finish = _start + old_sz;
				_end_of_storage = _start + n;
			}
		}

		void resize(size_t n, const _Ty& value = _Ty())
		{
			if(n <= size())
			{
				_finish = _start + n;
				return;
			}

			if(n > capacity())
			{
				reserve(n);
			}

			size_t offset = n - size();
			while(offset--)
			{
				*_finish++ = value;
			}
		}

	public:
		size_t size()const
		{
			return _finish - _start;
		}
		size_t capacity()const
		{
			return _end_of_storage - _start;
		}
		bool empty()const
		{
			return size() == 0;
		}
	public:
		void swap(vector& str)
		{
			std::swap(_start, str._start);
			std::swap(_finish, str._finish);
			std::swap(_end_of_storage, str._end_of_storage);
		}
	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_storage;
	};
};

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值