#ifndef STATICSEARCHLIST_H
#define STATICSEARCHLIST_H
#include <iostream>
#include <assert.h>
using namespace std;
const int defaultSize = 100;
template<class K,class T>
class StaticSearchList; //数据表类的前视定义
template<class K,class T>
struct DataNode //数据表中结点类的定义
{
K key; //关键码域
T data; //数据域
DataNode(){}
DataNode(const K x,const T y):key(x),data(y){}
template<class K,class T>
friend ostream& operator<<(ostream& out,DataNode<K,T>& el);
template<class K,class T>
friend istream& operator>>(istream& in,DataNode<K,T>& el);
};
template<class K,class T>
class StaticSearchList
{
public:
StaticSearchList(int sz = defaultSize):arraySize(sz),currentSize(0)
{
elements = new DataNode<K,T>[sz];
assert(elements != NULL);
}
StaticSearchList(StaticSearchList<K,T>& R); //复制构造函数
virtual ~StaticSearchList()
{
delete []elements;
}
virtual int Length() //求表的长度
{
return currentSize;
}
virtual K GetKey(int i)const //提取第i(从开始)个元素的关键域
{
assert(i>0 || i<=currentSize);
return elements[i-1].key;
}
virtual void SetKey(K x,int i) //修改第i(从开始)个元素的关键域
{
assert(i>0 || i<=currentSize);
elements[i-1].key = x;
}
virtual K GetData(int i)const //提取第i(从开始)个元素的数据域
{
assert(i>0 || i<=currentSize);
return elements[i-1].data;
}
virtual void SetData(K x,int i) //修改第i(从开始)个元素的数据域
{
assert(i>0 || i<=currentSize);
elements[i-1].data = x;
}
virtual int SeqSearch(const K x)const; //使用监视哨的顺序搜索
virtual int SeqSearch(const K x,int loc)const; //使用递归算法实现顺序搜索
virtual bool Insert(const K x,DataNode<K,T>& el); //在关键码为x的表项后插入el
virtual bool Insert(DataNode<K,T>& el); //在表的尾部插入新的表项
virtual bool Remove(const K x,DataNode<K,T>& el); //删除关键码为x的表项,通过el返回
template<class K,class T>
friend ostream& operator<<(ostream& out,const StaticSearchList<K,T>& OutList);
template<class K,class T>
friend istream& operator>>(istream& in,StaticSearchList<K,T>& InList);
/************************************************************************/
/* 以下函数针对有序顺序表 */
/************************************************************************/
virtual void SortMinToMax(); //将无序表按关键码从小到大排列
virtual void SortMaxToMin(); //将无序表按关键码从大到小排列
virtual int SequentSearch(const K x)const; //基于有序表的顺序搜索
virtual int BinarySearch(const K x)const; //基于有序表的迭代折半搜索
virtual int BinarySearch(const K x,int low,int high); //基于有序表的递归折半搜索
virtual void SequentInsert(DataNode<K,T>& el); //基于有序表的有序插入
int Begin() //定位第一个
{
return currentSize == 0 ? 0 : 1;
}
int Next(int i) //定位下一个
{
return (i>=1 && i<=currentSize) ? i+1 : 0;
}
protected:
DataNode<K,T> *elements; //数据表中存储数据的数组
int arraySize,currentSize; //数组的最大长度和当前长度
};
//在搜索表中顺序搜索其关键码为x的数据元素,要求数据元素在表中从下标开始存放,
//第currentSize号位置作为控制搜索过程自动结束的“监视哨”使用。若找到则函数
//返回该元素在表中的位置i,否则返回currentsize
template<class K,class T>
int StaticSearchList<K,T>::SeqSearch(const K x) const
{
elements[currentSize].key = x; //将x设置为监视哨
int i = 0;
while(elements[i].key != x)
++i;
return i+1;
}
//使用递归算法实现顺序搜索,先判断是否表尾,是则返回,表示搜索失败,此时loc(1<=loc<=currentSize)
//停留在currentSize+1位置。不是,再判断位于loc位置的元素的关键码是否等于x,是则搜索成功,返回元素的位置,
//否则算法递归检测下一个位置loc+1。该递归算法的调用语句形式为: int loc=1;int Pos=SeqSearch(x,loc);
template<class K,class T>
int StaticSearchList<K,T>::SeqSearch(const K x, int loc) const
{
if(loc > currentSize)
return 0; //搜索不成功
else if(elements[loc-1].key == x)
return loc; //搜索成功
else
return SeqSearch(x,loc+1); //继续递归搜索
}
template<class K,class T>
bool StaticSearchList<K,T>::Insert(DataNode<K,T> &el)
{
if(currentSize == arraySize) //表满,不能插入
return false;
elements[currentSize] = el;
++currentSize;
return true;
}
template<class K,class T>
bool StaticSearchList<K,T>::Insert(const K x,DataNode<K,T>& el)
{
if(currentSize == arraySize) //表满,不能插入
return false;
int i = SeqSearch(x); //查找键值为x的位置
if(i == currentSize)
return false;
for (int j=currentSize;j>i;--j)
elements[j] = elements[j-1];
elements[i] = el;
++currentSize;
return true;
}
template<class K,class T>
bool StaticSearchList<K,T>::Remove(const K x, DataNode<K,T> &el)
{
if(currentSize == 0)
return false;
int i = SeqSearch(x); //在表中定位到关键码为x的元素位置
if(i == currentSize)
return false; //未找到,返回
el = elements[i];
elements[i] = elements[currentSize-1]; //用尾元素填补被删除的位置
--currentSize;
return true;
}
template<class K,class T>
ostream& operator<<(ostream& out,const StaticSearchList<K,T>& OutList)
{
out<<"表的内容为:"<<endl;
for(int i=0;i<OutList.currentSize;++i)
out<<OutList.elements[i];
out<<endl;
out<<"表中含有的元素个数为:"<<OutList.currentSize<<endl;
return out;
}
template<class K,class T>
istream& operator>>(istream& in,StaticSearchList<K,T>& InList)
{
cout<<"请输入表的大小:";
in>>InList.currentSize;
cout<<"请依次输入这"<<InList.currentSize<<"个元素:"<<endl;
for(int i=0;i<InList.currentSize;++i)
{
cout<<"# "<<i+1<<":";
in>>InList.elements[i];
}
return in;
}
template<class K,class T>
ostream& operator<<(ostream& out,DataNode<K,T>& el)
{
out<<"key:"<<el.key<<ends<<"data:"<<el.data<<endl;
return out;
}
template<class K,class T>
istream& operator>>(istream& in,DataNode<K,T>& el)
{
cout<<"key:";
in>>el.key;
cout<<"data:";
in>>el.data;
return in;
}
/************************************************************************/
/* 以下函数针对有序顺序表实现 */
/************************************************************************/
template<class K,class T>
void StaticSearchList<K,T>::SortMinToMax()
{
for (int i=0;i<currentSize-1;++i)
{
int k=i;
for (int j=i+1;j<currentSize;++j)
{
if(elements[k].key > elements[j].key)
k = j;
}
if (i != k)
{
DataNode<K,T> temp;
temp = elements[i];
elements[i] = elements[k];
elements[k] = temp;
}
}
}
template<class K,class T>
void StaticSearchList<K,T>::SortMaxToMin()
{
for (int i=0;i<currentSize-1;++i)
{
int k=i;
for (int j=i+1;j<currentSize;++j)
{
if(elements[k].key < elements[j].key)
k = j;
}
if (i != k)
{
DataNode<K,T> temp;
temp = elements[i];
elements[i] = elements[k];
elements[k] = temp;
}
}
}
template<class K,class T>
int StaticSearchList<K,T>::SequentSearch(const K x) const
{
for(int i =1;i<=currentSize;++i)
if(elements[i-1].key == x) //成功,停止搜索
return i;
else if(elements[i-1].key > x) //不成功,停止搜索
break;
return 0; //顺序搜索失败
}
//折半搜索的迭代算法
template<class K,class T>
int StaticSearchList<K,T>::BinarySearch(const K x) const
{
int high = currentSize-1,low = 0,mid;
while (low <= high)
{
mid = (low + high) / 2;
if(x > elements[mid].key)
low = mid + 1;
else if(x < elements[mid].key)
high = mid - 1;
else
return mid+1; //搜索成功
}
return 0; //搜索失败
}
//折半搜索的递归算法,在搜索区间[low...high]采用折半搜索算法搜索给定元素匹配的元素
//此程序中low与high的值从到currentSize
template<class K,class T>
int StaticSearchList<K,T>::BinarySearch(const K x, int low, int high)
{
int mid = 0;
if (low <= high)
{
mid = (low + high) / 2;
if(x > elements[mid].key)
mid = BinarySearch(x,mid+1,high);
else if(x < elements[mid].key)
mid = BinarySearch(x,low,mid-1);
}
return mid;
}
//保持元素从小到大插入
template<class K,class T>
void StaticSearchList<K,T>::SequentInsert(DataNode<K,T>& el)
{
assert(currentSize<arraySize);
int i=1; //查找插入位置
while(i<=currentSize && elements[i-1].key<=el.key)
++i;
for(int j=currentSize;j>=i;--j)
elements[j] = elements[j-1];
elements[i-1]=el;
++currentSize;
}
#endif