STL入门基础 理解vector容器

目录

vector容器的接口使用

vector容器的模拟实现


STL是C++标准库的重要组成部分,vector容器在实际中非常的重要,它常见的接口使用我们都要熟悉,这一篇肝一波vector容器常见的接口使用,帮助大家深入理解

vector容器的接口使用

vector容器的初始化

//构造函数初始化
void test_vector1()
{
  //存储int
  vectorv1;
  v1.push_back(1);
  v1.push_back(2);
 
  //存储double
  vectorv2;
  v2.push_back(1.1);
  v2.push_back(2.2);

  //存储string
  vectorv3;
  v3.push_back("李白");//
  v3.push_back("杜甫");
  v3.push_back("苏轼");
  //用10个5初始化 
  vectorv4(10,5);
}

vector容器的遍历方法

//vector容器的遍历
void test_vector2()
{
  vectorv1;
  v1.push_back(1);
  v1.push_back(2);
  v1.push_back(3);
  v1.push_back(4);
  //1.下标+[]
  for (size_t i = 0; i < v1.size(); ++i)
  {
   cout << v1[i] << " ";//打印1 2 3 4
  }
  cout << endl;
  //2.迭代器
  vector::iterator it = v1.begin();
  while (it != v1.end())
  {
   cout << *it <<" ";//打印1 2 3 4
   ++it;
  }
  cout << endl;
  //3.范围for
  for (auto e : v1)
  {
   cout << e << " ";//打印1 2 3 4
  }
  cout << endl;
}

vector容器的空间增长问题

//测试增容 vs下
void test_vector3()
{
  size_t sz;
  vector v;
  v.reserve(100);//提前开辟空间 可以减少扩容
  sz = v.capacity();//初始容量 
  cout << "making v grow:\n";
  for (int i = 0; i < 100; ++i)
  {
   v.push_back(i);
   if (sz != v.capacity())
   {
    sz = v.capacity();
    cout << "capacity changed: " << sz << '\n';//扩容1.5倍
   }
  }
  //vector v1;
  //v1.resize(100, 1);// resize扩容同时初始化
  v.resize(10);
  cout << v.size() << endl;//打印10  resize扩容 不会缩容
  cout << v.capacity()<

vector容器指定位置插入删除

//指定位置插入 删除  
//使用迭代器 不支持下标
void test_vector4()
{
  vectorv1;
  v1.push_back(1);
  v1.push_back(2);
  v1.push_back(3);
  v1.push_back(4);
  //头插1个0
  v1.insert(v1.begin(), 0);
  for (auto e : v1)
  {
    cout << e << " ";//打印0 1 2 3 4
  }
  cout << endl;

  //第三个位置插入2
  v1.insert(v1.begin() + 3, 2);
  for (auto e : v1)
  {
    cout << e << " ";//打印0 1 2 2 3 4
  }
  cout << endl;

  //头删三次
  v1.erase(v1.begin());
  v1.erase(v1.begin());
  v1.erase(v1.begin());
  for (auto e : v1)
  {
    cout << e << " ";//打印2 3 4
  }
  cout << endl;
}

vector容器的查找

//要复用find查找函数 
void test_vector5()
{
  vectorv1;
  v1.push_back(1);
  v1.push_back(2);
  v1.push_back(3);
  v1.push_back(4);
  //查找3删除
  auto pos=find(v1.begin(), v1.end(), 3);
  if (pos != v1.end())
  {
   cout << "找到了" << endl;
   v1.erase(pos);//删除3
  }
  else
  {
   cout << "没有找到" << endl;
  }
  //遍历
  for (auto e : v1)
  {
   cout << e << " ";
  }
  cout << endl;
}

vector容器数据的排序

//调用sort排序
//随机访问迭代器 
void test_vector6()
{
  vectorv1;
  v1.push_back(1);
  v1.push_back(3);
  v1.push_back(9);
  v1.push_back(7);
  v1.push_back(10);
  sort(v1.begin(), v1.end());//默认升序 
  //sort(v1.begin(), v1.end(),greater());//使用仿函数排降序
  for (auto e : v1)
  {
   cout << e << " ";//1 3 7 9 10
  }
  cout << endl;
}

vector容器的模拟实现

模拟实现vector容器可以帮助我们更好的理解底层是如何实现的

模拟实现函数的接口

template
class vector
{
public:

	typedef T* iterator;
	typedef const T* const_iterator;

	//无参的构造
	vector()
		:_start(nullptr)
		, _finish(nullptr)
		, _endofstorage(nullptr)
	{}

	//带参构造 现代写法 迭代器区间 
	template 
	vector(InputIterator first, InputIterator last)
		:_start(nullptr)
		, _finish(nullptr)
		, _endofstorage(nullptr)
	{
		while (first != last)
		{
			push_back(*first);
			++first;
		}
	}
	//交换函数
	void swap(vector& v)
	{
		std::swap(_start, v._start);
		std::swap(_finish, v._finish);
		std::swap(_endofstorage, v._endofstorage);
	}
	//拷贝构造现代写法 复用带参构造
	vector(const vector& v)
		:_start(nullptr)
		, _finish(nullptr)
		, _endofstorage(nullptr)
	{
		vector tmp(v.begin(), v.end());
		this->swap(tmp);
		cout << "调用拷贝构造" << endl;
	}
	//赋值
	vector& operator=(vector v)
	{
		cout << "调用赋值" << endl;
		this->swap(v);
		return *this;
	}
	//析构
	~vector()
	{
		if (_start)
		{
			delete[]_start;
			_start = _finish = _endofstorage = nullptr;

		}
	}

	//大小
	size_t size()const
	{
		return _finish - _start;
	}
	//容量
	size_t capacity()const
	{
		return _endofstorage - _start;
	}

	//迭代器
	iterator begin()
	{
		return _start;
	}

	const_iterator begin()const
	{
		return _start;
	}

	iterator end()
	{
		return _finish;
	}

	const_iterator end()const
	{
		return _finish;
	}

	//扩容函数
	void reserve(size_t n)
	{
		size_t sz = size();
		if (n > capacity())
		{
			T* tmp = new T[n];//先开辟新空间
			if (_start)//有空间才拷贝
			{
				//memcpy(tmp, _start, size() * sizeof(T));//拷贝数据
				for (size_t i = 0; i < size(); ++i)
				{
					tmp[i] = _start[i];
				}
				delete[]_start;//释放旧空间
			}
			_start = tmp;//在指向新空间
		}
		//同时让finish和capacity都指向新空间
		_finish = _start + sz;
		_endofstorage = _start + n;
	}
	//扩容加初始化 注意分情况
	void resize(size_t n, const T& val = T())
	{
		if (n > capacity())
		{
			reserve(n);
		}
		if (n > size())
		{
			while (_finish < _start + n)
			{
				*_finish = val;
				++_finish;
			}
		}
		else
		{
			_finish = _start + n;
		}
	}

	//尾部插入数据
	void push_back(const T& x)
	{
		if (_finish == _endofstorage)
		{
			size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
			reserve(newcapacity);
		}
		*_finish = x;//插入到finish位置
		++_finish;//更新大小
	}
	//尾删数据
	void pop_back()
	{
		if (_finish > _start)
		{
			--_finish;
		}
	}
	//返回数据
	T& operator[](size_t pos)
	{
		assert(pos < size());
		return _start[pos];
	}
	const T& operator[](size_t pos)const
	{
		assert(pos < size());
		return _start[pos];
	}

	//pos位置插入x
	iterator insert(iterator pos, const T& x)
	{
		assert(pos >= _start && pos <= _finish);
		//先扩容
		if (_finish == _endofstorage)
		{
			size_t n = pos - _start;//扩容后pos失效,要更新
			size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
			reserve(newcapacity);
			pos = _start + n;
		}
		//挪动数据
		iterator end = _finish - 1;
		while (end >= pos)
		{
			*(end + 1) = *end;
			--end;
		}
		*pos = x;
		++_finish;

		return pos;
	}
	//erase 
	iterator erase(iterator pos)
	{
		assert(pos >= _start && pos < _finish);
		iterator it = pos + 1;
		while (it != _finish)
		{
			*(it - 1) = *it;
			++it;//...
		}
		--_finish;
		return pos;//指向最后被删除元素的后一个位置
	}

	void clear()
	{
		_finish = _start;
	}
private:
	iterator _start;
	iterator _finish;
	iterator _endofstorage;
};

模拟实现的测试

测试要和上面模拟接口放到一个命名空间里面

//尾插 尾删测试
void Test_vector1()
{
  vectorv;
  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);//头部插入0

  v.pop_back();//删除两个
  v.pop_back();
  vector::iterator it = v.begin();
  while (it != v.end())
  {
   cout << *it << " ";//打印0 1 2 3
   ++it;
  }
  cout << endl;
  }

//指定位置插入测试
void Test_vector2()
{
  vectorv;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  //指定位置偶数前插入20
  vector::iterator it = v.begin();
  while (it != v.end())
  {
   if (*it % 2 == 0)
   {
    //要考虑迭代器失效
    it = v.insert(it, 20);
    ++it;
   }
	++it;
  }
  for (auto e : v)
  {
   cout << e << " ";
  }
  cout << endl;
}

//指定位置删除 
void Test_vector3()
{
  vectorv;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  v.push_back(5);
  v.push_back(2);
  //删除偶数
  vector::iterator it = v.begin();
  while (it != v.end())
  {
	if (*it % 2 == 0)
	{
	 it = v.erase(it);
	}
	else
	{
	 ++it;
	}
  }

  for (auto e : v)
  {
   cout << e << " ";//打印1 3 5
  }
  cout << endl;
}

//迭代器区间初始化
void Test_vector4()
{
  vectorv;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  //迭代器模板
  vectorv1(v.begin(), v.end());

  std::string s("hello");
  vectorv2(s.begin(), s.end());

  for (auto e : v1)
  {
    cout << e << " ";//打印1 2 3 4
  }
  cout << endl;

  for (auto e : v2)
  {
    cout << e << "";//打印 hello
  }
  cout << endl;

}

//拷贝构造和赋值测试
void Test_vector5()
{
  vectorv;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  //迭代器区间
  vectorv1(v.begin(), v.end());
  for (auto e : v1)
  {
   cout << e << " ";
  }
  cout << endl;

  vectorv3(v);//调用构造 

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

学习vector一定要学会查看文档,这里放一个官方文档链接vector容器文档,vector在实际中非常的重要,我们只要熟悉常见的接口就可以

希望这篇文章大家有所收获,我们下篇见

你可能感兴趣的:(C++编程,c++,开发语言,大数据,容器)