vector详细解析

一、vector的初步认识

基础概念:vector是c++标准库(STL)的序列容器,支持动态调整大小,底层通过连续的内存实现。类似于动态数组。

  • vector需要包含头文件
  • vector随机访问效率高(O(1)),尾部插入/删除效率高(O(1)),中间/头部的操作效率低(O(n))

二、vector的相关使用

创建与初始化

int main()
{
	vector<int> v1;//无参构造
	vector<int> v2(10);//10个元素,默认值为0
	vector<int> v3(10, 20);//10个元素,值为20
	vector<int> v4(v3);//拷贝构造
	vector<int> v5 = { 0,1,3 };//列表初始化
	return 0;
}

插入元素

  • push_back
int main()
{
	vector<int> v1(3,6);//三个元素,值均为6
	v1.push_back(9);//尾部插入一个元素9
	for (auto a : v1)
	{
		cout << a << " ";
	}cout << endl;
	return 0;
}

  • insert

    在这里插入图片描述

int main()
{
	vector<int> v1(3, 6);//三个元素,值均为6
	for (auto a : v1)
			{
				cout << a << " ";
			}cout << endl;
	//插入单个元素,在v1.begin()位置之前插入元素,插入后,返回新插入元素的迭代器
	vector<int>::iterator it = v1.insert(v1.begin(), 5);
	for (auto a : v1)
	{
		cout << a << " ";
	}cout << endl;
	return 0;
}

int main()
{
	vector<int> v1 = { 1,2,3 };
	for (auto a : v1)
	{
		cout << a << " ";
	}cout << endl;
	//插入多个相同的元素,在v1.begin()+1位置之前插入元素,插入后,返回第一个新插入元素的迭代器
	vector<int>::iterator it = v1.insert(v1.begin()+1, 2,9);//插入两个9
	for (auto a : v1)
	{
		cout << a << " ";
	}cout << endl;
	return 0;
}

int main()
{
	//插入迭代器范围元素,返回值指向第一个新插入的元素的迭代器
	vector<int> src = { 2, 3 };
	vector<int> dest = { 1, 4 };
	//在dest.begin() + 1前插入,src.begin(), src.end()的元素,end指向最后一个元素的下一个位置
	dest.insert(dest.begin() + 1, src.begin(), src.end()); 
    // dest 变为 {1, 2, 3, 4}
	return 0;
}

int main()
{
	//插入一个初始化列表元素,返回值指向第一个新插入的元素
	vector<int> v = { 1, 5 };
	v.insert(v.begin() + 1, { 2, 3, 4 }); // v 变为 {1, 2, 3, 4, 5}
	return 0;
}

删除元素

  • pop_back

    int main()
    {
    	vector<int> v1 = { 1,2,3 };
    	v1.pop_back();//删除尾部元素
    	for (auto a : v1)
    	{
    		cout << a << " ";
    	}cout << endl;
    	return 0;
    }
    
  • erase
    在这里插入图片描述

    int main()
    {
    	vector<int> v = { 1,2,3,4,5,6 };
    	//删除单个元素,返回一个新的迭代器,指向被删除元素的下一个位置
    	v.erase(v.begin());
    	for (auto a : v)
    	{
    		cout << a << " ";
    	}cout << endl;
    	return 0;
    }
    
    int main()
    {
    	vector<int> v = { 1,2,3,4,5,6 };
    	auto first = v.begin() + 1;//指向第二个元素
    	auto last = v.begin() + 5;//指向第五个元素
    	//删除范围元素,删除第二个到第四个元素
    	v.erase(first, last);//左闭右开,[first,last)
    	for (auto a : v)
    	{
    		cout << a << " ";
    	}cout << endl;
    	return 0;
    }
    
  • clear

    清空所有元素,使size()为0,但保留capacity()不变,不会释放底层内存

    int main()
    {
    	vector<int> v = { 1,2,3,4,5,6 };
    	cout << v.size() << endl;
    	cout << v.capacity() << endl;
    	for (auto a : v)
    	{
    		cout << a << " ";
    	}cout << endl;
    	v.clear();
    	cout << v.size() << endl;
    	cout << v.capacity() << endl;
    	for (auto a : v)
    	{
    		cout << a << " ";
    	}cout << endl;
    	return 0;
    }
    

容量管理

  • size

    int main()
    {
    	vector<int> v = { 0,1,2 };
    	size_t n = v.size();//返回容器中实际存储元素的数量
    	cout << n << endl;
    	return 0;
    }
    
  • max_size

    int main()
    {
    	vector<int> v = { 0,1,2 };
    	size_t n = v.size();//返回容器中元素的大小
    	size_t m = v.max_size();
    	//返回vector中理论能存储的最大元素数量,由系统本身决定,不可修改,即使有足够内存,也可能因内存碎片化,无法达到
    	cout << n << endl;
    	cout << m << endl;
    	return 0;
    }
    
  • resize()

    resize调整容器元素数量。当n小于size,删除尾部多余的元素,使size的大小为n,但不改变底层空间的大小(capacity);当n大于size,会自动扩容,使size的大小为n,扩大capacity,尾部添加默认值0,也可以自己手动修改默认值

    int main()
    {
    	vector<int> v = { 1,2,3 };
    	cout << v.size() << " " << v.capacity() << endl;
    	v.resize(1);//n<size
    	cout << v.size() << " " << v.capacity() << endl;
    	for (auto a : v)
    	{
    		cout << a << " ";
    	}cout << endl;
    	
    	return 0;
    }
    
    int main()
    {
    	vector<int> v = { 1,2,3 };
    	cout << v.size() << " " << v.capacity() << endl;
    	v.resize(6);//n>size
    	cout << v.size() << " " << v.capacity() << endl;
    	for (auto a : v)
    	{
    		cout << a << " ";
    	}cout << endl;
    	return 0;
    }
    
    int main()
    {
    	vector<int> v = { 1,2,3 };
    	cout << v.size() << " " << v.capacity() << endl;
    	v.resize(6, 9);//n>size,将默认值修改为9
    	cout << v.size() << " " << v.capacity() << endl;
    	for (auto a : v)
    	{
    		cout << a << " ";
    	}cout << endl;
    	return 0;
    }
    
  • capacity

    int main()
    {
    	vector<int> v = { 1,2,3 };
    	size_t n = v.capacity();//返回当前分配的内存空间的大小,可能等于size,也可能大于size
    	size_t m = v.size();
    	cout << n << " "<<m<<endl;
    	return 0;
    }
    
  • reserve(n)

    reserve用于预分配内存,不改变元素的数量size,仅改变底层容量capacity。当n<=capacity不会有任何操作,只有当n>capacity,才会分配新内存,可以避免多次重复扩容

    int main()
    {
    	vector<int> v(10);
    	cout << v.size() << " " << v.capacity() << endl;
    	v.reserve(2);//n<capacity
    	cout << v.size() << " " << v.capacity() << endl;
    	return 0;
    }
    
    int main()
    {
    	vector<int> v(10);
    	cout << v.size() << " " << v.capacity() << endl;
    	v.reserve(20);//n>capacity
    	cout << v.size() << " " << v.capacity() << endl;
    	return 0;
    }
    
  • empty

    判断容器是否为空,size为0,就返回true,否则就返回false

    int main()
    {
    	vector<int> v;
    	cout << v.empty() << endl;
    	v.push_back(1);
    	cout << v.empty() << endl;
    	v.clear();
    	cout << v.empty() << endl;
    	return 0;
    }
    
  • shrink_to_fit

    缩减内存,但不一定使内存变为size()

    int main()
    {
    	vector<int> v(1);
    	v.resize(100);
    	cout << v.capacity() <<" "<< v.size() << endl;
    	v.clear();
    	cout << v.capacity() <<" "<< v.size() << endl;
    	v.shrink_to_fit();
    	cout << v.capacity() <<" "<< v.size() << endl;
    }
    

访问元素

  • operator[]

    int main()
    {
    	vector<int> v = { 1,2,3,4 };
    	cout << v[0] << endl;//通过索引访问,不检查是否越界
    	v[0] = 100;
    	cout << v[0] << endl;//修改元素
    	//cout << v[10] << endl;//越界访问,抛异常
    	return 0;
    }
    
  • at()

    它在访问时会进行边界检查,在越界时会抛出异常,但效率比operayor[]低,返回元素的引用

    int main() {
        vector<int> vec = {10, 20, 30};
        cout << vec.at(1); // 输出 20
        // 修改元素
        vec.at(2) = 99;        
        // 越界访问(触发异常)
        try {
            int x = vec.at(5);  // 索引5超出size()=3
        } catch (const std::out_of_range& e) {
            std::cerr << "错误: " << e.what() << "\n"; // 输出异常信息
        }
        return 0;
    }
    
  • front()与back()

    int main()
    {
    	vector<int> v = { 1,2,3 };
    	cout << v.front() << endl;//返回第一个元素的引用
    	cout << v.back() << endl;
    	v.front() = 9;//修改front元素
    	cout << v.front() << endl;
    	v.clear();
    	//cout << v.front() << endl;//容器为空,数据错误
    	return 0;
    }
    

迭代器

  • begin()与end()

    begin()用于获取指向容器第一个元素的迭代器,若容器为空,则begin()==end();end()用于获取指向容器末尾之后位置的迭代器。

    int main()
    {
    	vector<int> v = { 9,8,7,6,5,4,3,5 };
    	for (auto it = v.begin(); it != v.end(); it++)//遍历容器
    	{
    		cout << *it << " ";
    	}cout << endl;
    	sort(v.begin(), v.end());//算法排序
    	for (auto it = v.begin(); it != v.end(); it++)
    	{
    		cout << *it << " ";
    	}cout << endl;
    	return 0;
    }
    
  • rbegin()与rend()

    逆向迭代器,rbegin()指向最后一个元素的逆向迭代器,rend()指向第一个元素之前的位置的逆向迭代器,若容器为空则rbegin()==rend()。

    int main()
    {
    	vector<int> v = { 9,8,7,6,5,4,3,2,1 };
    	for (auto it = v.rbegin(); it != v.rend(); it++)//遍历容器,逆向迭代器的++会向容器的头部移动
    	{
    		cout << *it << " ";
    	}cout << endl;
    	sort(v.rbegin(), v.rend());//算法排序
    	for (auto it = v.begin(); it != v.end(); it++)
    	{
    		cout << *it << " ";
    	}cout << endl;
    	return 0;
    }
    
  • cbegin()与cend()

    只允许读,不允许修改的迭代器,若在只读不写的情况下,使用它更加安全

三、vector的简单实现

namespace mystl
{
	template<class T>
	class vector
	{
		typedef T* iterator;
		typedef const T* const_iterator;
	public:

		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin()const
		{
			return begin();
		}
		const_iterator end()const
		{
			return _finish;
		}



		vector(size_t n, const T& val = T())
		{
			return resize(n, val);
		}

		template<class InputIterator>
		vector(InputIterator first,InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				first++;
			}
		}
		vector(const vector<T>& v)
			:_start(nullptr), _finish(nullptr), _endofstorage(nullptr)
		{
			reserve(v.capacity());
			for (auto a : v)
			{
				push_back(a);
			}
		}
		vector(const vector<T>& v)
		{
			_start = new[v.capacity()];
			for (size_t i = 0; i < v.size(); i++)
			{
				_start[i] = v._start[i];
			}
			_finish = _start + v.size();
			_endofstorage = _start + v.capacity();
		}

		void swap(vector<T>& v)
		{
			std::swap(_start.v._start);
			std::swap(_finish, v._finish);
			std::swap(_endofstorage, v._endofstorage);
		}
		vector<T>& operator=(vector<T>& v)
		{
			swap(v);
			return *this;
		}

		~vector()
		{
			if (_start)
			{
				_start = _finish = _endofstorage = nullptr;
			}
		}
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t sz = size();
				T* tmp = new T[n];
				if (_start)
				{
					for (size_t i = 0; i < sz; i++)
					{
						tmp[i] = _start[i];
					}
					delete[] _start;
				}
				_start = tmp;
				_finish = _start+sz;
				_endofstorage = _start+n;
			}
		}
		void resize(size_t n, const T& val = T())
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				reserve(n);
				while (_finish != (_start + n))
				{
					*_finish = val;
					_finish++;
				}
			}
		}
		void push_back(const T& x)
		{
			if (_finish == _endofstorage)
			{
				size_t newcapacity = capacity() == 0 ? 4 : capacity() *= 2;
				reserve(newcapacity);
			}
			*_finish = x;
			++_finish;
		}
		void pop_back()
		{
			erase(--end());
		}
		size_t capacity()const
		{
			return _endofstorage - _start;
		}
		size_t size()const
		{
			return _finish - _start;
		}

		T& operator[](size_t pos)
		{
			assert(pos < size());
			return _start[pos];
		}
		const T& operator[](size_t pos)const
		{
			assert(pos < size());
			return _start[pos];
		}


		iterator insert(iterator pos, const T& x)
		{
			assert(pos >= _start && pos <= _finish);
			if (_finish == _endofstorage)
			{
				size_t len = pos - _start;
				size_t newcapacity = capacity() == 0 ? 4 : capacity() *= 2;
				reserve(newcapacity);
				pos = _start + len;
			}
			iterator end = _finish - 1;
			while (end > pos)
			{
				*end + 1 = *end;
				--end;
			}
			*pos = x;
			_finish++;
			return pos;
		}
        
		iterator erase(iterator pos)
		{
			assert(pos >= _start && pos < _finish);
			iterator it = pos + 1;
			while (it != _finish)
			{
				*it - 1 = *it;
				++it;
			}
			_finish--;
			return pos;
		}
	private:
		iterator _start = nullptr;//指向数据块的开始
		iterator _finish = nullptr;//指向有效数据的结尾
		iterator _endofstorage = nullptr;//指向存储容量的结尾
	};
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值