本文使用c++实现vector数据结构,vector的接口函数采用高效的实现方式,这样一方面使我加深对数据结构的理解,另一方便可以让我再回顾回顾c++,之前写了好久python都快把c++忘记了。
操作 | 功能 | 对象 |
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
}