STL库vector模拟实现

STL的vector容器是一种动态数组,它实现了在尾部插入或删除元素时,时间复杂度为O(1),而在头部或中部插入或删除元素时,时间复杂度为线性阶O(n)。相比静态数组,vector可以动态扩展内存空间,而不需要像数组那样预先分配固定的内存空间。

vector容器的迭代器是支持随机访问的迭代器,这使得vector在访问元素时具有很高的效率。vector容器提供了许多操作函数,例如push_back()用于在尾部添加元素,erase()用于删除元素,insert()用于在指定位置插入元素等。

在C++中,vector容器的定义方式为:std::vector<T> v;其中,std是命名空间,vector是类名,T是存储元素的类型,v是对象名。可以通过使用push_back()函数或者使用下标运算符[]来向vector中添加或访问元素。

vector容器是一种非常实用的动态数组,它具有高效的插入、删除和访问功能,并且可以动态扩展内存空间。

构造函数和析构函数

         vector()//构造函数
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{}

		~vector()//析构函数
		{
			delete[] _start;
			_start = _finish = _endofstorage = nullptr;
		}

获取第一个和最后一个数据

       iterator begin()//第一个位置(迭代器)
		{
			return _start;
		}

		iterator end()//最后一个位置的下一位
		{
			return _finish;
		}

		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}

扩容函数和下标访问

void reserve(size_t n)//扩容函数
		{
			if (n > capacity())
			{
				size_t sz = size();
				T* tmp = new T[n];
				if (_start)
				{    
                     //memcpy会有增容问题(按字节拷贝造成浅拷贝
					//memcpy(tmp, _start, sizeof(T) * sz);
					for(size_t i=0;i<sz;i++)
					{
						tmp[i] = _start[i];//调用operator=,是深拷贝
					}
					delete[] _start;
				}
				_start = tmp;
				_finish = tmp + sz;
				_endofstorage = tmp + n;

			}
		}

		T& operator[](size_t i)//下标访问
		{
			assert(i < size());
			return _start[i];
		}

		const T& operator[](size_t i) const//const下标访问
		{
			assert(i < size());
			return _start[i];
		}

删除数据和拷贝构造

        void pop_back()//删除数据
		{
			/*assert(_start > _finish);//不能把_start前面的数据删了
			--_finish;*/

			erase(_finish - 1);//复用
		}

		//vector(const vector<T>& v)//实现拷贝构造v2(v),不写会造成浅拷贝问题
		//{
		//	_start = new T[v.capacity()];//v2要开空间
		//	_finish = _start;
		//	_endofstorage = _start + v.capacity();

		//	for (size_t i = 0; i < v.size(); i++)//把v的数据给v2
		//	{
		//		*_finish = v[i];
		//		++_finish;
		//	}
		//}

		vector(const vector<T>& v)//v2(v),效果同上,先把v2初始化为空
			:_start(nullptr)
			,_finish(nullptr)
			,_endofstorage(nullptr)
		{
			reserve(v.capacity());//把v2扩容一下
			for (const auto& e : v)//遍历v,把v的数据插入到v2
			{
				push_back(e);
			}
		}

         iterator erase(iterator pos)//删除pos位置的值
		{
			assert(pos < _finish);//pos要指向有效位置
			iterator it = pos;
			while (it < _finish)//从后往前挪动覆盖
			{
				*it = *(it + 1);
				++it;
			}
			--_finish;
			return pos;//返回pos位置的下一个数据,但把pos删了,pos位置的下一个数据就是pos
		}

改变容量函数和operator运算符重载

           
        void resize(size_t n, const T& val = T())
		{
		    if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				if (n > capacity())
				{
					reserve(n);
				}
				while (_finish < _start + n)//扩容的数据都填上val
				{
					*_finish = val;
					++_finish;
				}
			}
		}

		vector<T>& operator=(vector<T> v)//v1=v3简单写法
		{
			swap(v);
			return *this;
		}

迭代器和插入数据

    void insert(iterator pos, const T& x)//在pos位置插入数据
		{
			assert(pos <= _finish);// =是尾插
			if (_finish == _endofstorage)//扩容
			{
				size_t n = pos - _start;//计算扩容前pos位置之前的数据长度
				size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;
				reserve(newcapacity);
				pos = _start + n;//若增容原来的pos会失效,需要重新计算位置
			}

			iterator end = _finish - 1;
			while (end >= pos)//挪动数组的数据,pos也要挪动
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = x;
			++_finish;
		}

        void print_vector(const vector<int>& v)//只读迭代器
		{
			vector<int>::const_iterator it = v.begin();
			while (it != v.end())
			{
				//*it += 1;
				cout << *it << " ";
				it++;
			}
			cout << endl;
		}


		void push_back(const T& x)//尾插数据
		{
			//if (_finish == _endofstorage)//满了就扩容
			//{
			//	size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;
			//	reserve(newcapacity);
			//}
			//*_finish = x;
			//++_finish;

			insert(_finish,x);
		}

有效数据和容量

        size_t size() const//有效数据个数
		{
			return _finish - _start;
		}

		size_t capacity() const//总容量
		{
			return _endofstorage - _start;
		}

代码整合+测试

namespace LXQ1
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
    
    //把以上代码拷贝过来

     void swap(vector<T>& v)//为何要自己写swap?因为库函数使用深拷贝代价大
		{
			::swap(_start, v._start);//交换指针,调用全局的swap
			::swap(_finish, v._finish);
			::swap(_endofstorage, v._endofstorage);
		}

private:
		iterator _start;//指向第一个位置
		iterator _finish;//指向最后位置的下一位
		iterator _endofstorage;//  等于_start+capacity
	};

	void print_vector(const vector<int>& v)
	{
		vector<int>::const_iterator it = v.begin();//返回的是第一个位置的指针
		while (it != v.end())//end是最后一个位置的下一个位置
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}


	void test1()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.push_back(6);
		v.push_back(7);

		print_vector(v);
		cout << v.size() << endl;
		cout << v.capacity() << endl;

		vector<int>::iterator it = v.begin();
		while (it!=v.end())
		{
			*it += 1;
			cout << *it << " ";
			it++;
		}
		cout << endl;

		for (auto& e : v)//底层是迭代器
		{
			e -= 1;//auto e没有改变指针,只是改变了e,需要auto& e
			cout << e<< " ";
		}
		cout << endl;

		for (size_t i = 0; i < v.size(); i++)
		{
			cout << v[i]<< " ";
		}
		cout << endl;

	}

	void test2()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.insert(v.begin(), 0);//头插
		for (size_t i = 0; i < v.size(); i++)
		{
			cout << v[i] << " ";
		}
		cout << endl;

		vector<int>::iterator it = v.begin();//删除偶数(迭代器失效问题)
		while (it != v.end())
		{
			if (*it % 2 == 0)
			{
				it = v.erase(it);//一定要获取返回值,否则迭代器失效
			}
			else
			{
				it++;
			}
		}
		for (size_t i = 0; i < v.size(); i++)
		{
			cout << v[i] << " ";
		}
		cout << endl;

	}

	void test3()
	{
		vector<int> v;
		v.reserve(10);
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
		v.push_back(6);
		v.push_back(7);
		
		print_vector(v);
		cout << v.size() << endl;
		cout << v.capacity() << endl << endl;

		v.resize(4);
		print_vector(v);
		cout << v.size() << endl;
		cout << v.capacity() << endl << endl;

		v.resize(8);//默认给缺省值
		print_vector(v);
		cout << v.size() << endl;
		cout << v.capacity() << endl << endl;

		v.resize(12,12);//填上12
		print_vector(v);
		cout << v.size() << endl;
		cout << v.capacity() << endl << endl;
	}

	void test4()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);
	
		for (size_t i = 0; i < v1.size(); i++)
		{
			cout << v1[i] << " ";
		}
		cout << endl;

		vector<int> v2(v1);//拷贝构造
		for (size_t i = 0; i < v2.size(); i++)
		{
			cout << v2[i] << " ";
		}
		cout << endl;

		vector<int> v3;
		v3.push_back(10);
		v3.push_back(20);
		v3.push_back(30);
		v3.push_back(40);
		v3.push_back(50);

		v1 = v3;
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}

	void test5()
	{
		vector<string> v;
		v.push_back("111333333333333333333333");
		v.push_back("22266666666666666666666666");
		v.push_back("2226666666000666666666669999999 ");
        //程序会崩溃,当T是string时的增容问题,本质是memcpy造成的浅拷贝问题
		
		for (auto e : v)
		{
			cout << e << " ";
		} 
		cout << endl;
	}
}

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值