数据结构——向量——向量模板源码

来源:互联网 发布:linux tcp backlog 编辑:程序博客网 时间:2024/06/11 02:36

推荐文章:那些年,做的几个应用     

 自己动手写了一个向量模板,模板函数的定义与实现本该写在同一个文件里的,为了查找方便分开了。定义写在头文件,实现写在源文件了。

本页内容:

a.头文件("myVector.h")

b.源文件(“myVector.cpp")

c.模板测试文件("mainVTest.cpp")

向量模板实现源码:

a.头文件("myVector.h"):

#ifndef _MYVECTOR_H__#define _MYVECTOR_H__typedef int Rank;//秩 #define DEFAULT_CAPACITY  3 //默认的初始容量(实际应用中可设置为更大)  template <typename T> class myVector { //向量模板类 protected:   Rank _size; int _capacity;  T* _elem; //规模、容量、数据区   void copyFrom ( T const* A, Rank lo, Rank hi ); //复制数组区间A[lo, hi)   void expand(); //空间不足时扩容   void shrink(); //装填因子过小时压缩   bool bubble ( Rank lo, Rank hi ); //扫描交换   void bubbleSort ( Rank lo, Rank hi ); //起泡排序算法   Rank max ( Rank lo, Rank hi ); //选取区间[lo,hi)间的最大元素   int  maxoftwo(int one,int two){ if(one>two) return one; else return two; }//选取两者之间的最大值    Rank binSearch(T*A,T const&e,Rank lo,Rank hi) const;//二分查找 public: // 构造函数    myVector ( int c = DEFAULT_CAPACITY, int s = 0, T v = 0 ) //容量为c、规模为s、所有元素初始为v    { _elem = new T[_capacity = c]; for ( _size = 0; _size < s; _elem[_size++] = v ); } //s<=c        myVector ( T const* A, Rank n ) { copyFrom ( A, 0, n ); } //数组整体复制    myVector ( T const* A, Rank lo, Rank hi ) { copyFrom ( A, lo, hi ); } //区间    myVector ( myVector<T> const& V ) { copyFrom ( V._elem, 0, V._size ); } //向量整体复制    myVector ( myVector<T> const& V, Rank lo, Rank hi ) { copyFrom ( V._elem, lo, hi ); } //区间     // 析构函数    ~myVector() { delete [] _elem; } //释放内部空间 // 只读访问接口    Rank size() const { return _size; } //规模    T get(Rank r) const;//获取秩为r的元素    void put(Rank r,T e);//用e替换秩为r的数值     Rank insert ( Rank r, T const& e ); //插入元素    Rank insert ( T const& e ) { return insert ( _size, e ); } //默认作为末元素插入    int remove ( Rank lo, Rank hi ); //删除秩在区间[lo, hi)之内的元素    T remove ( Rank r ){ T e=_elem[r];remove(r,r+1); return e;} //删除秩为r的元素    int disordered() const; //判断向量是否已排序    void sort ( Rank lo, Rank hi ); //对[lo, hi)排序    void sort() { sort ( 0, _size ); } //整体排序    Rank find ( T const& e ) const { return find ( e, 0, _size ); } //无序向量整体查找    Rank find ( T const& e, Rank lo, Rank hi ) const; //无序向量区间查找    Rank search ( T const& e ) const //有序向量整体查找    { return ( 0 >= _size ) ? -1 : search ( e, 0, _size ); }    Rank search ( T const& e, Rank lo, Rank hi ) const; //有序向量区间查找    int deduplicate(); //无序去重    int uniquify(); //有序去重    bool empty() const { return !_size; } //判空  // 重载     T& operator[] ( Rank r ) const{return _elem[r];}; //重载下标操作符,可以类似于数组形式引用各元素    myVector<T> & operator= ( myVector<T> const& ); //重载赋值操作符,以便直接克隆向量 // 遍历    void traverse ( void (*visit ) ( T& ) ); //遍历(使用函数指针,只读或局部性修改)    template <typename VST> void traverse ( VST& ); //遍历(使用函数对象,可全局性修改)  }; //Vector#include"myVector.cpp"#endif 

b.源文件("myVector.cpp"):

      

/***************protected函数实现****************/ //复制数组区间A[lo, hi)--"copyFrom"函数template<typename T>void myVector<T>::copyFrom(T const*A,Rank lo,Rank hi){_size=hi-lo;//获取向量规模_capacity=hi-lo;//获取向量容量_elem=new T[_capacity];//生成向量数据区(此时向量处于饱和状态) for(int i=lo;i<hi;i++){_elem[i]=A[i];}} //向量空间不足时扩容--"expand"函数 template<typename T>void myVector<T>::expand(){ if(_size<_capacity){ return;//尚未满员时,不必扩容} _capacity=maxoftwo(_capacity,DEFAULT_CAPACITY);//不低于最小容量T*oldElem=_elem;//原向量指针保存 _elem=new T[_capacity<<=1];//容量加倍for(int i=0;i<_size;i++)//复制原向量内容 {_elem[i]=oldElem[i];//T为基本类型 ,或已重载赋值操作符"=" } delete [] oldElem;//释放原空间 }//装填因子过小时压缩空间--"shrink"函数template<typename T>void myVector<T>::shrink(){if(_size<_capacity/2){T*oldElem=_elem;//原向量指针保存_elem=new T[_capacity>>=1];//容量缩减一半 for(int i=0;i<_size;i++)//复制原向量内容{_elem[i]=oldElem[i];//T为基本类型 ,或已重载赋值操作符"="} }}//扫描交换--"bubble"函数 template<typename T> bool myVector<T>::bubble(Rank lo,Rank hi){bool sorted=true;//整体有序标志while(++lo<hi){if(_elem[lo-1]>_elem[lo])//自做向右,逐一检查各对相邻元素 {sorted=false; //逆序 T temp;//交换 temp=_elem[lo-1];_elem[lo-1]=_elem[lo];_elem[lo]=temp;}} return sorted; }//起泡排序算法template<typename T>void myVector<T>::bubbleSort(Rank lo,Rank hi){while(!bubble(lo,hi--));//逐趟做扫描交换,直至全部有序 }//选取区间[lo,hi)间的最大元素template<typename T>Rank myVector<T>::max(Rank lo,Rank hi){T maxT;Rank rank;maxT=_elem[lo];for(int i=lo;i<hi;i++){if(maxT<_elem[i]){rank=i;maxT=_elem[i];}} return rank;}/****************public函数实现******************/ //获取秩为r的元素template<typename T>T myVector<T>::get(Rank r) const{return _elem[r];}//向向量写入数值--"put"函数template<typename T>void myVector<T>::put(Rank r,T e){_elem[r]=e;//用e替换秩为r的数值 } //插入元素--"insert"函数template<typename T>Rank myVector<T>::insert(Rank r,T const& e){expand();//如果有必要,扩容for(int i=_size;i>r;i--)//自后向前 {   _elem[i]=_elem[i-1];//后继元素顺次后移一个单元 } _elem[r]=e;//置入新元素 _size++;// 更新容量 return r;//返回秩  }//删除秩在区间[lo, hi)之内的元素--"remove"函数 template<typename T>int myVector<T>::remove(Rank lo,Rank hi){  if(lo==hi){  return 0;}    while(hi<_size)    { _elem[lo++]=_elem[hi++];//[hi,_size)顺次前移hi-lo位     }    _size=lo;//更新规模     shrink();// 如有必要,缩容     return hi-lo;//返回被删除元素的数目}// 判断向量是否已排序--"disordered"函数template<typename T>int myVector<T>::disordered() const{int n=0;//计数器for(int i=1;i<_size;i++)//逐一检查各对相邻元素 {  n+=(_elem[i-1]>_elem[i]);//逆序则计数 } return n;//向量有序当且仅当n=0 }//对区间[lo,hi)排序(排序接口)--"sort"函数 template<typename T>void myVector<T>::sort(Rank lo,Rank hi){bubbleSort(lo,hi);}//无序向量[lo,hi)区间查找--"find"函数template<typename T>Rank myVector<T>::find( T const& e, Rank lo, Rank hi ) const//在向量中查找元素,并返回秩最大者 {while((lo<hi--)&&e!=_elem[hi]) ;//逆向查找  return hi;//hi<lo意味着失败;否则hi即命中元素的秩 }//有序向量[lo,hi)区间查找--"search"函数template<typename T>Rank myVector<T>::search(T const &e,Rank lo,Rank hi) const{return binSearch(_elem,e,lo,hi);//二分查找 }//无序去重--"deduplicate"函数template<typename T>int myVector<T>::deduplicate(){int oldSize=_size;//记录原规模Rank i=1;//从_elem[1]开始while(i<_size)//自前向后逐一考查各元素_elem[i] {  if(find(_elem[i],0,i)<0)//在前缀中寻找雷同者   {      i++;//若无雷同则继续考查其后继  }   else  {   remove(i);//否则删除雷同者        }}    return oldSize-_size;//向量规模变化量。即删除元素总数} //有序去重--"uniquify"函数template<typename T>int myVector<T>::uniquify(){int oldSize=_size;//记录原规模     int i=0;//从首元素开始     while(i<_size-1)//从前向后逐一比对各队相邻元素     {      (_elem[i]==_elem[i+1])?remove(i+1):i++;//若雷同,则删除后者;否则转至后后一元素 }return oldSize-_size;//向量规模变化量。即删除元素总数}//遍历--"traverse"函数 //遍历1--利用函数指针进行只读或局部性修改template<typename T>void myVector<T>::traverse(void (*visit ) ( T& )) {for(int i=0;i<_size;i++){visit(_elem[i]);}}//遍历2--利用对象机制可进行全局性修改template<typename T>template<typename VST>void myVector<T>::traverse(VST &visit){for(int i=0;i<_size;i++){visit(_elem[i]);}}/************其他函数**************///二分查找(有序向量可用) template<typename T>Rank myVector<T>::binSearch(T*A,T const&e,Rank lo,Rank hi) const {Rank mi;    while(lo<hi)//每步迭代可能要做两次比较判断,有3个分支     {    mi=(lo+hi)>>1;//以中点为轴点     if(e<A[mi]) hi=mi;//深入前半段[lo,mi)继续查找     else if(A[mi]<e) lo=mi+1;//深入后半段(mi,hi)     else return mi;//在mi处待命 }if(e<A[mi]){return mi-1;//查找失败}else{return mi;//查找失败} <pre>}

c.模板测试文件("mainVTest.cpp"):

#include<iostream>#include"myVector.h"#include<cstdlib>using namespace std;myVector<int> VTest;void CoutVTest(); void DisturbVTest();template <typename T> void visit(T e){e++;}int main(){for(int i=0;i<20;i++){VTest.insert(i);}cout<<"初始向量(insert加入,get读取):"<<endl; CoutVTest();    //测试函数    cout<<"测试函数:"<<endl;//size()cout<<"size()="<<VTest.size()<<endl;//put(int r,T e)VTest.put(0,20);//将0号元素换为20 cout<<"put(0,20)=";CoutVTest();//insert(2,100)VTest.insert(2,100); cout<<"insert(2,100)=";CoutVTest();//remove(4)VTest.remove(4);cout<<"remove(4)=";CoutVTest();VTest.remove(0,10);cout<<"remove(0,10)=";CoutVTest();//disordered()cout<<"disordered()="<<VTest.disordered()<<endl;VTest.put(0,100);cout<<"After put(0,100)=";CoutVTest();cout<<"Then disordered()="<<VTest.disordered()<<endl;//sort()VTest.sort();cout<<"sort()=";CoutVTest();cout<<"After New VTest=";DisturbVTest();CoutVTest();VTest.sort(0,5);cout<<"sort(0,5)=";CoutVTest();//find(41)cout<<"find(41)="<<VTest.find(41)<<endl;cout<<"find(1000)="<<VTest.find(1000)<<endl;cout<<"find(41,0,5)="<<VTest.find(41,0,5)<<endl;cout<<"find(41,5,10)="<<VTest.find(41,5,10)<<endl;// search(4)VTest.sort();cout<<"After sort()=";CoutVTest();cout<<"search(41)="<<VTest.search(41)<<endl;cout<<"search(50)="<<VTest.search(50)<<endl;//deduplicate()VTest.put(2,58);VTest.put(9,58);cout<<"After New VTest=";CoutVTest(); cout<<"deduplicate()="<<VTest.deduplicate()<<endl;CoutVTest();//uniquify()VTest.sort();VTest.insert(3,58);VTest.insert(3,58);cout<<"After New VTest=";CoutVTest(); cout<<"uniquify()="<<VTest.uniquify()<<endl;CoutVTest(); //traverse()VTest.traverse(visit);cout<<"traverse()=";CoutVTest();cout<<"测试结束!"; return 0;} void CoutVTest(){for(int i=0;i<VTest.size();i++){cout<<VTest.get(i)<<" ";}cout<<endl;}void DisturbVTest(){for(int i=0;i<VTest.size();i++){VTest.put(i,rand()%100);}}



    

   

1 0