C++ STL_vector

stl中vector特点:

空间连续,当内存不够时候会自动扩容,控容是自动进行的,由分配器来做这件事。

当空间不够的时候,他是在另外一个地方开辟当前空间的俩倍,然后把当前内容都拷贝过去。

参考代码:

通过耗时来看,发现对于vector直接进行寻找某个值和排序之后在寻找某个值,前者耗时不一定比后者慢

#pragma once
#include<iostream>

using std::cout;
using std::cin;
using std::string;
long get_a_target_long() 
{
	long target = 0;
	cout << "target (0~" << RAND_MAX << "):";
	cin >> target;
	return target;
}
string get_a_target_string()
{
	long target = 0;
	char buf[10];
	cout << "target (0~" << RAND_MAX << "):" << endl;
	cin >> target;
	sprintf_s(buf, "%d", target);
	return string(buf);
}
int compareLongs(const void* a, const void* b)
{
	return *(long*)a - *(long*)b;
}
int compareStrings(const void*a, const void*b)
{
	if (*(string*)a > *(string*)b)
		return 1;
	else if (*(string*)a < *(string*)b)
		return -1;
	else
		return 0;
}


#pragma once
#include<vector>
#include<ctime>
#include<algorithm>
#include"function.h"

using std::endl;
using std::vector;
using std::exception;
using std::sort;
namespace stl_vector
{
	void test_vector(long& value)
	{
		cout << "test vector" << endl;
		vector<string> c;
		char buf[10];
		clock_t timeStart = clock();
		for (long i = 0; i < value; i++)
		{
			try {
				sprintf_s(buf, 10,"%d", rand());
				c.push_back(string(buf));
			}
			catch (exception& p) {
				cout << "i:" << i << " " << p.what() << endl;
				abort();
			}
		}
		cout << "milll-second:" << clock() - timeStart << endl;
		cout << "vector.size():" << c.size() << endl;
		cout << "vector.front():" << c.front().c_str() << endl;
		cout << "vector.back():" << c.back().c_str() << endl;
		cout << "vector.data():" << c.data() << endl;
		cout << "vector.capatity():" << c.capacity() << endl;

		string target = get_a_target_string();
		{
			timeStart = clock();
			auto pItem = std::find(c.begin(), c.end(), target);
			cout << "find(),mill-seconds:" << (clock() - timeStart) << endl;
			if (pItem != c.end())
				cout << "found," << (*pItem).c_str() << endl;
			else
				cout << "not found" << endl;
		}
		{
			timeStart = clock();
			sort(c.begin(), c.end());
			string* pItem = (string*)bsearch(&target, c.data(), c.size(), sizeof(string),compareStrings);
			cout << "sort + bsearch(),mill-seconds:" << (clock() - timeStart) << endl;
			if (pItem != NULL)
				cout << "found," << (*pItem).c_str() << endl;
			else
				cout << "not found" << endl;
		}

	}
}

二、vector中push_back、insert如何增加空间:

通过剖析源码可以看到,vector在每次增加函数的时候会判断当前空间是否够用,如果不够用则以俩倍的空间扩容.

#pragma once
/*
当我们以push_back将新元素插入vector尾端时,该函数首先检查是否还有备用空间,如果有就直接在备用空间上构造元素
并调整迭代器finish,使vector变大。如果没有没有备用空间了,就扩充空间(重新配置,移动数据,释放原空间);

*/
#include<iostream>
using std::iterator;
using std::_Construct;
using std::copy_backward;
using std::_Alloc_allocate;
using std::unexpected;
using std::_Destroy;
using std::_Deallocate;
template <class T,class Alloc = alloc>

class vector {
public:
	void push_back(const T& x)
	{
		if (finish != end_of_storage//还有备用空间
		{
			_Construct(finish, x); 
			++finish;//调整水位高度
		}
		else
		{
			insert_aux(end(), x);//
		}
	}
	void insert_aux(iterator position, const T& x)
	{
		if (start != end_of_storage)
		{
			//在备用空间起始处构造一个元素,并以vector最后一个元素值为初值
			_Construct(finish, *(finish - 1));
			++finish;
			T x_copy = x;
			copy_backward(position, finish - 2, finish - 1);
			*position = x_copy;
		}
		else {
			const size_type old_size = size();
			const size_type len = old_size != 0 ? 2 * old_size : 1;
			iterator new_start = _Alloc_allocate(len);
			iterator new_finish = new_start;
			try {
				//将原vector的内容拷贝到新vector
				new_finsih = uninitialized_copy(start, position, new_start);
				//为新元素设定初值x
				_Construct(new_finsih, x);
				//调整水位
				++new_finish;
				//为什么会有这一步么?因为这个Insert_aux函数不只被push_back函数调用,还会被Insert函数调用,所有需要把插入点之后的数据
				//在之后的的数据拷贝过来;
				//将安插点的原内容也拷贝过来
				new_finish = uninitialized_copy(position, finish, new_finish;
			}
			catch (unexpected &p)
			{
				cout << "unexception " << p.what();
			}
			//析构并释放原vector;
			_Destroy(begin(), end());
			_Deallocate();
			start = new_start;
			finish = new_finish;
			end_of_storage = new_start + len;
			
		}
	}
protected :
	iterator start;
	iterator finish;
	iterator end_of_storage;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值