排序与查找
此处的查找方法基于顺序表。
对半查找递归算法
template <typename T,int size> int Orderedlist<T,size>::Binarysearch(T & x,const int low,const int high)
{ // x为定值
int mid=-1; //mid赋初值是关键!否则找不到时可能出错停机
if (low<=high)
{
mid=(low+high)/2;
if(slist[mid]<x) mid=Binarysearch(x,mid+1,high);
//中间点小于定值,查找右区间,注意mid+1
else if(x<slist[mid]) mid=Binarysearch(x,low,mid-1);
//中间点大于定值,查找左区间,注意mid-1
}
return mid; // 找到返回下标,未找到但结束了,返回mid=-1
}
递归方法易于理解,但是效率低,简化的类模板如下:
#include<iostream>
using namespace std;
template <typename T,int size>class Orderedlist
{
int maxsize;
int last;
T slist[size];
public:
Orderedlist(){last=-1;maxsize=size;}
int Binarysearch(T & x,const int low,const int high);
bool Insert(T & elem,int i);
void print();
// 无关成员函数省略
};//再次指出分号不可少
template <typename T,int size> bool Orderedlist<T,size>::Insert(T & elem ,int i)
{
int j;
if (i<0||i>last+1||last==maxsize-1) return false;
else
{
last++;
for (j=last;j>i;j--) slist[j]=slist[j-1];
slist[i]=elem;
return true;
}
}
template <typename T,int size> int Orderedlist<T,size>::Binarysearch(T & x,const int low,const int high)
{ // x为定值
int mid=-1; //mid赋初值是关键!否则找不到时可能出错停机
if (low<=high)
{
mid=(low+high)/2;
if(slist[mid]<x) mid=Binarysearch(x,mid+1,high);
//中间点小于定值,查找右区间,注意mid+1
else if(x<slist[mid]) mid=Binarysearch(x,low,mid-1);
//中间点大于定值,查找左区间,注意mid-1
}
return mid; // 找到返回下标,未找到但结束了,返回mid=-1
}
template <typename T,int size> void Orderedlist<T,size>::print()
{
int i;
for(i=0;i<=last;i++)
{
slist[i].show();
if(i%5==4) cout<<endl;
}
cout<<endl;
}
class Element
{
int key;
// 其他域省略
public:
bool operator<(Element ele){return key<ele.key;}
void putkey(int k){key=k;}
void show(){cout<<key<<'\t';}
};//重载了比较运算符,元素的比较,实际是元素关键字的比较
int main()
{
const int h=19;
int i,k=37;
Orderedlist<Element,100> ordlist;
int a[h]={67,61,59,53,47,43,41,37,31,29,23,19,17,13,11,7,5,3,2};//降序
Element n[h],elem;
for(i=0;i<h;i++) n[i].putkey(a[i]);
for(i=0;i<h;i++) ordlist.Insert(n[i],0); //始终在0号元素插入,建立升序顺序表
elem.putkey(k);
ordlist.print();
i=ordlist.Binarysearch(elem,0,h-1);
cout<<"整数"<<k<<"在表中位置(下标):"<<i<<endl;
k=33;
elem.putkey(k);
i=ordlist.Binarysearch(elem,0,h-1);
cout<<"整数"<<k<<"在表中位置(下标):"<<i<<endl;
return 0;
}
对半查找迭代算法
template <typename T,int size> int Orderedlist<T,size>::Binarysearch(T & x)const
{
int high=last ,low=0,mid; // last 当前有序表最大下标
if(last==-1) return -1; //避免空表出错
while(low<=high)
{
mid=(low+high)/2;
if(x<slist[mid]) high=mid-1; //左缩查找区间
else if(slist[mid]<x) low=mid+1;// 右缩查找区间
else return mid;
}
if(slist[mid]!=x) mid=-1;
return mid;
}
插入排序
template<typename T,int size>void Orderedlist<T,size>::InsertSort()
{
T temp;
int i,j;
for (i=1;i<=last;i++)
{
temp=slist[i];
j=i;
while (j>0&&temp<slist[j-1])
{
slist[j]=slist[j-1];
j--; //查找与移动同时做
}
slist[j]=temp;
}
}
交换排序
template <typename T,int size> void Orderedlist<T,size>::BubbleSort()
{
bool noswap;
int i,j;
T temp;
for (i=0;i<last;i++)
{ //最多做n-1趟
noswap=true; //未交换标志为真
for(j=last;j>i;j--)
{ //从下往上冒泡
if(slist[j]<slist[j-1])
{
temp=slist[j];
slist[j]=slist[j-1];
slist[j-1]=temp;
noswap=false;
}
}
if(noswap) break; //本趟无交换,则终止算法。
}
}
以学生类为数组元素的源程序:
#include<iostream>
#include<string>
using namespace std;
template <typename T,int size>class Orderedlist
{
int maxsize;
int last;
T slist[size];
public:
Orderedlist(){last=-1;maxsize=size;}
void BubbleSort();
bool Insert(T & elem,int i);
void print();
// 无关成员函数省略
};//再次指出分号不可少
template <typename T,int size> bool Orderedlist<T,size>::Insert(T & elem ,int i){……}
template <typename T,int size> void Orderedlist<T,size>::print(){……}
template <typename T,int size> void Orderedlist<T,size>::BubbleSort(){……}
class student
{
int id ; //学号
string name; // 姓名
char sex; // 性别
int age; // 年龄
string address; //家庭地址
float eng, phy, math, electron; //英语,物理,数学和电子学成绩
public:
student(){}
student(int,string,char,int,string,float,float,float,float);
bool operator<(student ele){return id<ele.id;}
void show(){cout<<id<<'\t'<<name<<'\t'<<sex<<'\t'<<age<<'\t'<<address<<'\t'
<<eng<<'\t'<<phy<<'\t'<<math<<'\t'<<electron<<endl;}
};
student::student(int i,string n,char s,int a,string add,float en,float ph,float ma,float ele)
{
id=i;
name=n;
sex=s;
age=a;
address=add;
eng=en;
phy=ph;
math=ma;
electron=ele;
}
int main()
{
const int h=4;
int i;
Orderedlist<student,100> ordlist;
student n[h]={
student(6004327,"张菲",'m',19,"北京路58号",80,85,90,78),
student(6004121,"关雨",'w',19,"天津路64号",88,75,91,68),
student(6004118,"刘蓓",'w',18,"上海路37号",78,95,81,88),
student(6004219,"赵昀",'m',18,"重庆路95号",78,95,81,88)
};
for(i=0;i<h;i++) ordlist.Insert(n[i],i); //建立顺序表
cout<<"未排序表:"<<endl;
ordlist.print();
ordlist.BubbleSort();
cout<<"已排序表:"<<endl;
ordlist.print();
return 0;
}
选择排序
template <typename T,int size> void Orderedlist<T,size>::SelectSort()
{
int i,j,k;
T temp;
for(i=0;i<last;i++)
{
k=i;
temp=slist[i];
for(j=i;j<=last;j++)
if(slist[j]<temp)
{
k=j;
temp=slist[j];
}
if(k!=i)
{
temp=slist[i];
slist[i]=slist[k];
slist[k]=temp;
}
}
}