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

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

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

本页内容:

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);
	}
}



    

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值