【数据结构】模拟实现Vecotr

cpp 复制代码
namespace my_vector
{

	template <class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;//常量指针,指针指向的值不可以变;
        
		//构造函数
		vector()
			:start(nullptr)
			,finish(nullptr)
			,end_of_storage(nullptr)
		{
		    

		}
		//析构函数
		~vector()
		{
			delete[] start;
			start = finish = end_of_storage = nullptr;	
		}

		

		//const T& x=T();   这个的生命周期从一行被延长为当前作用域结束;无论是内置类型还是自定义类型都可以采用匿名形式
		vector(int n,const T& val=T())
			:start(nullptr)
			, finish(nullptr)
			, end_of_storage(nullptr)
		{
		
			for (int i=0;i<n;++i)
			{
				push_back(val);
			}

		}

//迭代器构造函数,即便是string类的迭代器也能拷贝,只是把char类型转成int(打比方)类型,所以会造成空间浪费;
//不同类型的迭代器拷贝可能引起数据丢失和越界问题或者浪费空间等问题);
		//模板   
		template<class InputIterator>
		vector(InputIterator first,InputIterator last)
		{
			while (first!=last)
			{
				//vs库里面的迭代器不是原生指针,而是被封装好的类;
				push_back(*first);//这里不能用自定义类型会出现"非法寻址"的问题
				++first;
			}
		 
		}

		//拷贝构造函数
		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			//浅拷贝:memcpy(start,v.start,sizeof(t)*v.size());
			
			//深拷贝
			for(int i=0;i<v.size();++i)
			{
				start[i] = v.start[i];//里面如果是自定义类型,会调用赋值函数构造每一个对象(会自己开辟空间,在下面90行已经实现深层赋值,针对vector<t>)属于深拷贝;
			}
			finish = start + v.size();
			end_of_storage = start + v.capacity();
		}

		vector(initializer_list<T> i1)
		{
			//常量数组结构体对象
			initializer_list<T> ::iterator it = i1.begin();
			while (it!=i1.end())
			{
				push_back(*it);
				++it;
			}
		
		}

		void swap(vector<T>& v)
		{
			std::swap(start,v.start);
			std::swap(finish, v.finish);
			std::swap(end_of_storage, v.end_of_storage);		
		}

		vector<T>& operator=(vector<T> v)
		{
			swap(v);
			return *this;
		}

		void reserve(size_t n)  
		{
			//需要的空间大于原容量才进行扩容
			if (n > capacity())
			{
				T* tmp = new T[n];
				size_t sz = size();
				if (start)//如果原来的空间不为空,那么就直接拷贝原来所有的元素(如果是自定义类型,会两次析构);
				{
					//memcpy(tmp,start,sizeof(T)*size());
					for (int i=0;i<size();++i)
					{
						tmp[i] = start[i];//深拷贝
					}
					delete[] start;
				}

				start = tmp;
				finish = tmp + sz;
				end_of_storage = tmp + n;
			}
		
		
		}
		//扩容+初始化
		void resize(size_t n,T val=T())
		{ 
			if (n>capacity())
			{
				reserve(n);
				while (finish!=end_of_storage)
				{
					*finish = val;
					++finish;
				}

			}
			else
			{

				if (n < size())
				{
					//删除数据
					finish = start + n;
				}

			}
		}

		//迭代器失效问题:野指针(扩容引起)
		iterator insert(iterator pos,const T& val)
		{
			assert(pos<=finish);
			assert(pos>=start);

			
			//判断是否需要扩容
			if (finish==end_of_storage)
			{    
				int len = pos - start;
				size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newCapacity);
				//扩容会导致pos迭代器失效,需要更新一下;
				pos = start + len;
			}

			iterator end = finish - 1;
			while (end>=pos)
			{
				*(end+1) = *end;
				--end;
			}
			*pos = val;
			++finish;
			return pos;//返回更改后的形参pos,让pos指向插入的元素,也就是原来指向的前一个;
		}


		iterator erase(iterator pos)
		{
			assert(pos <finish);
			assert(pos >= start);
            
			iterator end = pos+1;
     		while (end<finish)
			{
				*(end - 1) = *end;
				++end;
			}
			--finish;
			return pos;
		}

		void push_back(const T& x)
		{
			if (finish==end_of_storage)
			{
				reserve(capacity()==0?4:capacity()*2);             
			}
			*finish = x;
			++finish;
		}
	    
		void pop_back()
		{
			assert(!empty());
			--finish;
		}

		bool empty()
		{
			return start == finish;
		}

		T& operator[](size_t pos)//无符号整数pos,如果pos为-1,那么就是int型正整数的最大值;
		{
			assert(pos < size());
			return *(start + pos);
		}

		 T& operator[](size_t pos)const//无符号整数pos,如果pos为-1,那么就是int型正整数的最大值;
		{
			assert(pos < size());
			return *(start + pos);
		}
		

        //迭代器不要引用返回,因为如果++或--迭代器,vector容器里面也会更改;
		iterator begin() 
		{
			return start;
		}

		const_iterator begin()const
		{
			return start;
		}

		iterator end() 
		{
			return finish;
		}
		const_iterator end()const
		{
			return finish;
		}
		const size_t size() const
		{
			return finish - start;
		}

		const size_t capacity() const
		{
			return end_of_storage - start;
		}

	private:
		iterator start;
		iterator finish;
		iterator end_of_storage;
	};
}
相关推荐
xlq223221 小时前
22.多态(上)
开发语言·c++·算法
666HZ6661 小时前
C语言——高精度加法
c语言·开发语言·算法
sweet丶1 小时前
iOS MMKV原理整理总结:比UserDefaults快100倍的存储方案是如何炼成的?
算法·架构
D_evil__2 小时前
[C++高频精进] 并发编程:线程基础
c++
云里雾里!2 小时前
力扣 209. 长度最小的子数组:滑动窗口解法完整解析
数据结构·算法·leetcode
Mr_WangAndy2 小时前
C++17 新特性_第二章 C++17 语言特性_std::any和string_view
c++·string_view·c++40周年·c++17新特性·c++新特性any
CoderYanger3 小时前
递归、搜索与回溯-穷举vs暴搜vs深搜vs回溯vs剪枝:12.全排列
java·算法·leetcode·机器学习·深度优先·剪枝·1024程序员节
憨憨崽&3 小时前
进击大厂:程序员必须修炼的算法“内功”与思维体系
开发语言·数据结构·算法·链表·贪心算法·线性回归·动态规划
水天需0104 小时前
C++ 三种指针转换深度解析
c++
chem41114 小时前
C 语言 函数指针和函数指针数组
c语言·数据结构·算法