一、【数据结构】向量(vector)的实现

本文使用c++实现vector数据结构,vector的接口函数采用高效的实现方式,这样一方面使我加深对数据结构的理解,另一方便可以让我再回顾回顾c++,之前写了好久python都快把c++忘记了。

vector接口列表
操作功能对象
vector(int c, Rank s, T v)设置容量、初始大小、元素初始值 
vector(int c, Rank s)设置容量、初始大小 
vector(initializer_list<T>)列表初始化方式构造 
vector(const vector<T>& A, Rank lo, Rank hi)从另一vector拷贝构造新vector对象 
~vector()析构函数,手动释放动态数组所占的空间 
expand()容量更新(扩容)向量
sharink()容量更新(缩减)向量
display()打印vector内部元素向量
size()返回vector当前有效尺寸向量
get(Rank r)获取指定元素向量
put(Rank r, const T e)替换指定元素向量
permute()打乱vector顺序向量
unsort(Rank lo, Rank hi)打乱vector指定区间的顺序向量
find(Rank lo,Rank hi,const T e)在指定区间查找指定元素向量
insert(Rank r, const T& e)在指定区间插入元素向量
insert(const T& e)在尾部插入元素向量
remove(Rank lo, Rank hi)删除指定区间的元素向量
remove(Rank r)删除单个元素向量
deduplicate()除去重复元素向量
traverse(void(*func)(T& a))用指定函数批量处理元素(函数指针方式)向量
traverse(FunClass func)用指定函数批量处理元素(函数对象方式)向量
disordered()判断是不是有序向量向量
uniquify()除去重复元素有序向量
search(Rank lo, Rank hi, const T e)在指定区间中查找元素有序向量
binsearch(Rank lo, Rank hi, const T e)在指定区间中查找元素(二分查找)有序向量
sort(Rank lo, Rank hi, int a)排序算法汇总向量
bubbleSort(Rank lo, Rank hi)冒泡排序向量
mergeSort(Rank lo, Rank hi)归并排序向量
重载运算符[]下标运算符向量
重载运算符=赋值运算符向量
重载运算符=赋值运算符(列表赋值方式)向量
重载运算符==相等判断运算符向量
重载运算符<=小于等于判断运算符向量
重载运算符>=大于等于判断运算符向量
#pragma once
#define DEFAULT_CAPACITY 10 //默认容量大小
using namespace std;
typedef int Rank;

template <typename T>
class vector
{
protected:
	Rank _size;
	int _capacity;
	T *_elem; //vector内部所维护的数组的指针
public:
	//构造函数(容量,初始大小,初始值)
	vector(int c = DEFAULT_CAPACITY, Rank s = 0, T v = 0);
	vector(initializer_list<T>);    //列表初始化方式
	vector(const vector<T>& A, Rank lo, Rank hi);
	//析构函数
	~vector();

	//复制构造函数
	void copyFrom(const vector<T>& A, Rank lo, Rank hi);

	//容量更新(扩容和缩减)
	void expand();		
	void sharink();      

	//普通成员函数
	void display() const; //打印vector内部元素
	Rank size() const;    //返回vector当前size
	T get(Rank r);        //获取指定元素
	void put(Rank r, const T e);  //替换指定元素
	void permute();       //打乱顺序
	void unsort(Rank lo, Rank hi);  //打乱区间顺序
	Rank find(Rank lo,Rank hi,const T e);           //查找指定元素
	Rank insert(Rank r, const T& e); // 插入
	Rank insert(const T& e);       //在向量尾部插入
	int remove(Rank lo, Rank hi); //删除指定区间的元素
	T remove(Rank r);           //删除指定索引的单个元素
	void deduplicate();			  //除去重复元素
	void traverse(void(*func)(T& a));  //用指定函数批量处理元素(函数指针方式)
	template<typename FunClass> void traverse(FunClass func);             //用指定函数批量处理元素(函数对象方式)
	bool disordered() const;      //判断是不是有序向量
	void uniquify();              //有序向量除去重复元素
	Rank search(Rank lo, Rank hi, const T e); //有序向量,在指定区间中查找元素
	Rank search(const T e);
	Rank binsearch(Rank lo, Rank hi, const T e); //有序向量,二分查找
	void swap(T& a, T& b);        //交换元素值
	void sort(Rank lo, Rank hi, int a);    //排序算法汇总
	void bubbleSort(Rank lo, Rank hi);     //冒泡排序
	void mergeSort(Rank lo, Rank hi); //归并排序(递归实现)
	//重载运算符
	T& operator[](const Rank i) const;           //下标运算符
	vector<T>& operator=(const vector<T> &A);    //赋值运算符
	vector<T>& operator=(initializer_list<T>);   //赋值运算符,列表初始化
	bool operator==(const vector<T>& A);         //判等运算符
	bool operator<=(const vector<T>& A);         //小于等于判断
	bool operator>=(const vector<T>& A);         //大于等于判断
};

//实现c++中vector容器底层(具体实现也要放在与声明同样的文件中)

template <typename T> vector<T>::vector(int c, Rank s, T v)
{
	_elem = new T[_capacity = c];  //申请容量为T*c的内存空间并用_elem指针指向该地址
	for (_size = 0; _size < s; _elem[_size++] = v);  //对有效值进行初始化并更新_size
}

template<typename T> vector<T>::vector(initializer_list<T> li)
{
	_elem = new T[_capacity = li.size()];
	for (auto iter = li.begin(); iter != li.end(); iter++)
		_elem[_size++] = *iter;
}

template <typename T> vector<T>::vector(const vector<T>& A, Rank lo, Rank hi)
{
	copyFrom(A, lo, hi);
}


template <typename T> vector<T>::~vector()
{
	//释放数组中的空间
	delete[] _elem;
}

template <typename T> void vector<T>::copyFrom(const vector<T>& A, Rank lo, Rank hi)
{
	_capacity = (hi - lo) << 1;
	_size = 0;
	_elem = new T[_capacity];  //申请内存
	while (lo < hi)
	{
		_elem[_size++] = A[lo++];
	}
}

template<typename T> void vector<T>::display() const
{
	if (_size)
	{
		for (int i = 0; i < _size - 1; i++)
		{
			cout << _elem[i] << ",";
		}
		cout << _elem[_size - 1] << endl;
	}
}

//重载[]运算符
template<typename T> T& vector<T>::operator[](const Rank i) const
{
	return _elem[i];
}

template<typename T> vector<T>& vector<T>::operator=(const vector<T> &A)
{
	//释放之前的空间,后面会自动创建
	delete[] _elem;
	copyFrom(A, 0, A.size());
	return *this;  //返回this的引用才能连续赋值A=B=C
}

template<typename T> vector<T>& vector<T>::operator=(initializer_list<T> li)
{
	delete[] _elem;
	_size = 0;
	_capacity = li.size() << 1;
	_elem = new T[_capacity];  //申请内存
	for(auto iter=li.begin();iter!=li.end(); iter++)
		_elem[_size++] = *iter;

	return *this;
}

template<typename T> Rank vector<T>::size() const
{
	return _size;
}

template<typename T> T vector<T>::get(Rank r)   
{
	return _elem[r];
}

template<typename T> void vector<T>::put(Rank r, const T e)
{
	_elem[r] = e;
}

template<typename T> void vector<T>::expand()
{
	if (_size < _capacity) return;
	if (_capacity < DEFAULT_CAPACITY) _capacity = DEFAULT_CAPACITY;
	T* oldElem = _elem; _elem = new T[_capacity <<= 1];
	for (int i = 0; i < _size; i++)
		_elem[i] = oldElem[i];
	delete[] oldElem;
}


//{
//	//cout << "enpand():the old capacity: " << _capacity << endl;
//	if (_capacity < DEFAULT_CAPACITY) _capacity = DEFAULT_CAPACITY;
//	if ((_capacity >> 1) < _size) {  //如果_capacity不大于_size的两倍,扩容
//		T* tempPtr = new T[_capacity=(_size << 1)];
//		//cout << "_size" << _size << endl;
//		for(int i=0;i<_size;i++)
//		{
//			tempPtr[i] = _elem[i];  //转移数据
//			//cout << "i:" << i << endl;
//		}
//		delete[] _elem;  //清除之前的空间
//		_elem = tempPtr; //指针指向新的空间 
//	}
//	//cout << "enpand():the new capacity: " << _capacity << endl;
//}


template<typename T> void vector<T>::sharink()
{
	//cout << "sharink():the old capacity: " << _capacity << endl;
	if (_size < _capacity/4.0)   //_size小于_capacity的1/4,缩减
	{
		T *tempPtr = ((_size << 1) > DEFAULT_CAPACITY) ? new T[_capacity =(_size<<1)] : new T[_capacity = DEFAULT_CAPACITY];
		for (int i = 0; i < _size; i++)
		{
			tempPtr[i] = _elem[i];
			//cout << "i:" << i << endl;
		}
		delete[] _elem;
		_elem = tempPtr;   //更新指针指向
	}
	//cout << "sharink():the new capacity: " << _capacity << endl;

}

template<typename T> void vector<T>::permute()
{
	for(int i=0;i<_size;i++)
	{
		swap(_elem[i], _elem[rand()%_size]);   //随机找一个替换
	}
}


template<typename T> void vector<T>::unsort(Rank lo,Rank hi)
{
	for (int i = lo; i < hi; i++)
	{
		swap(_elem[i], _elem[rand() % (hi - lo) + lo]);
	}
}

template<typename T> bool vector<T>::operator==(const vector<T>& A)
{
	if (_size != A.size()) return false;
	for (int i = 0; i < _size; i++)
	{
		if(_elem[i] != A[i]) return false;
	}
	return true; 
}

template<typename T> bool vector<T>::operator<=(const vector<T>& A)
{
	int min = (_size <= A.size()) ? _size : A.size();
	for (int i = 0; i < min; i++)
	{
		if ((*this)[i] != A[i])
			return ((*this)[i] <= A[i]) ? true : false;
	}
	return (_size <= A.size()) ? true : false;
}

template<typename T> bool vector<T>::operator>=(const vector<T>& A)
{
	int min = (_size <= A.size()) ? _size : A.size();
	for (int i = 0; i < min; i++)
	{
		if ((*this)[i] != A[i])
			return ((*this)[i] >= A[i]) ? true : false;
	}
	return (_size >= A.size()) ? true : false;
}

template<typename T>  Rank vector<T>::find(Rank lo, Rank hi, const T e)  //	前闭后开
{

	while ((hi--)>lo)
	{
		if(_elem[hi] == e) break;
	}
	return hi;
}

template<typename T> Rank vector<T>::insert(Rank r, const  T& e)
{	
	expand();
	//Rank从r至以后的元素都要往后面移一位
	for (int i = _size; i > r; i--)
	{
		_elem[i] = _elem[i - 1];
	}
	_elem[r] = e;
	_size++;
	return r;
 }

template<typename T> Rank vector<T>::insert(const T& e)
{
	return insert(_size, e);
}

template<typename T> int vector<T>::remove(Rank lo, Rank hi)   //前闭后开
{
	//首先指定后界秩后面的元素都往前面移动(hi-lo+1)个位置,原位置置零
	if (lo == hi) return 0;
	while(hi<_size)
	{
		_elem[lo++] = _elem[hi];
		_elem[hi++] = 0;
	}
	//更新_size
	_size -= (hi - lo);
	sharink();
	return (hi - lo);
}

template<typename T> T vector<T>::remove(Rank r)
{
	T e = _elem[r];
	remove(r, r + 1);
	return e;
}

template<typename T> void vector<T>::deduplicate()
{
	if (!_size) return;

	Rank rl = 0;   //第rl个是已经确认无重的最后一个
	Rank rr = 1;   //第rr个是要判断的
	while (rr < _size)  // _size会减,rr会加
	{
		if (find(0, rl + 1, _elem[rr]) >= 0)    //确认是之前出现过
			remove(rr);
		else
		{
			rl++;       //加入一个有效值
			rr++;
		}
	}
}

template<typename T> void vector<T>::traverse(void(*func)(T& a))
{
	for (int i = 0; i < _size; i++)
	{
		func(_elem[i]);
	}
}

template<typename T> template<typename FunClass> void vector<T>::traverse(FunClass func)
{
	for (int i = 0; i < _size; i++)
	{
		func(_elem[i]);
	}
}


template<typename T> bool vector<T>::disordered() const
{
	for (int i = 0; i < _size - 1; i++)
	{
		if (_elem[i] > _elem[i + 1])
		{
			return false;
		}
	}
	return true;
}

template<typename T> void vector<T>::uniquify()
{
	if (_size<=1) return;
	Rank rl=0;    //已经确认好的序列的最后一个元素的秩
	Rank rr=1;    //正要判断的元素的秩
	while (rr < _size)
	{
		if (_elem[rr] != _elem[rr - 1])  //发现一个新值,移动到rl+1
		{
			_elem[++rl] = _elem[rr++];
		}
		else
			rr++;
	}
	_size = rl + 1;
	sharink();
}

template<typename T> Rank vector<T>::search(Rank lo, Rank hi, const T e)
{
	return binsearch(lo, hi, e);
}

template<typename T> Rank vector<T>::search(const T e)
{
	return (_size <= 0) ? -1 : search(0, _size, e);
}

template<typename T> Rank vector<T>::binsearch(Rank lo, Rank hi, const T e)    //  [0][1][2][m][4][5][6][7][-hi-]
{
	//方法一
	//把mi这一点作为一个分界线,单数直接作为右侧区间的左端点
	Rank mi;
	while (lo < hi)
	{
		mi = (lo + hi) >> 1;   //取中点的时候是往左偏的
		(e < _elem[mi]) ? hi = mi : lo = mi+1;     //都是左闭右开区间
	}
	return --lo;
}
																			   																																					   
//{   //方法二
//	Rank mi;
//	while (lo<hi)
//	{
//		mi = (lo + hi) >> 1;
//		if (_elem[mi] < e)
//			lo = mi + 1;
//		else if(_elem[mi] > e)
//			hi = mi;   //都是左闭右开区间
//		else
//			return mi;
//		}
//	return -1;
//}

template<typename T> void vector<T>::swap(T& a, T& b)
{
	a = a^b;      //原理:(a^b)^a=b
	b = a^b;
	a = a^b;  
}


template<typename T> void vector<T>::sort(Rank lo, Rank hi, int a)
{
	switch (a)
	{
		case 1:
			bubbleSort(lo, hi); break;   //冒泡排序
		case 2:;
			//selectSort(lo, hi); break;   //选择排序
		case 3:
			mergeSort(lo, hi); break;    //归并排序
		case 4:;
			//heapSort(lo, hi); break;     //堆排序
		default:;
			//quickSort(lo, hi); break;    //快速排序
	}
}

template<typename T> void vector<T>::bubbleSort(Rank lo, Rank hi)
{
	bool sorted = false;   //已有序标志
	while (!sorted)        //如果有序,提前退出
	{
		sorted = true;
		for (int i = lo; i < hi - 1; i++)  //在一次循环中如果发现逆序,就置标志位为false
		{
			
			if (_elem[i] > _elem[i + 1])
			{
				sorted = false;
				swap(_elem[i], _elem[i + 1]);
			}
			
		}
		hi--;
	}
}

template<typename T> void vector<T>::mergeSort(Rank lo, Rank hi)  //左闭右开区间
{
	if (!(lo < hi-1)) //只有一个元素则不用排序
		return;
	Rank mi = (lo + hi) >> 1;          //[0][1][2] [3]
	mergeSort(lo, mi);
	mergeSort(mi, hi);

	//开始归并
	T* A = _elem + lo;
	T* C = _elem + mi;
	int lb = mi - lo;  //1
	int lc = hi - mi;  //2
	T* B = new T[lb];  
	for (int i = 0; i < lb; i++)
		B[i] = A[i];    //复制元素到新空间
	//比较B和C所指序列的大小,将结果放置在A处
	for (int a=0, i = 0, j = 0; i < lb || j < lc;)
	{
		if (i < lb&&j < lc)       //两个序列都还有剩余
			A[a++] = (B[i] < C[j]) ? B[i++] : C[j++];
		if (i < lb && !(j < lc))  //只有B序列还有剩余
			A[a++] = B[i++];
		if (!(i < lb) && j < lc)  //只有C序列还有剩余
			A[a++] = C[j++];
	}
	delete[] B;  //有new就要有delete
}

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值