#include
#include
#include
#include
#include
#include
#include
#define MAX 200 // 数组元素的最大个数
typedef int datatype;
typedef struct //定义记录为结构体类型
{
int Date; //关键字域
datatype other; //其他域
}Key;
Key *s1,S[MAX];
class paixu //声明一个排序类
{
public:
paixu(){} //构造函数为空
~paixu(){} //析构函数为空
void createA(int n); //键盘输入数据
void createB(int n); //随机产生数据
void createrandnum(int a[],int n);
void frontdisplayList(Key L[], int n);//输出未排数据
void reardisplayList(Key L[], int n); //输出已排数据
void face1(); //欢迎界面
char choose(); //选择数据产生方式
void meun(); //选择排序算法
void face2(); //欢迎推出界面
void SelectSort(Key L[],int n); //选择排序
void InsertSort(Key L[],int n); //插入排序
void BubbleSort(Key L[],int n); //冒泡排序
void merge(Key L[], int low, int m, int high);//归并排序
void merge_one(Key L[], int lenth, int n);
void mergesort(Key L[], int n);
void ShellSort(Key L[],int n); //希尔排序
int partition(Key L[],int s,int t); //一轮快速排序
void QuickSort(Key L[], int first, int last); //快速排序
void sift(Key L[], int i, int m);
void HeapSort(Key L[], int n); //堆排序
};
void paixu::SelectSort(Key L[],int n)
{//选择排序算法
//其思路是把待排数组视为两部分L[0..i]为已排部分L[i..n-1]为未排部分
int i,j,k;
int temp;
for(i=0;i
{
k=i;
for(j=i+1;j
if(L[k].Date>L[j].Date) //找最小元L[k]
k=j;
if(k!=i)
{
temp=L[i].Date; //放入已排部分
L[i].Date=L[k].Date;
L[k].Date=temp;
}
}
return;
}
void paixu::InsertSort(Key L[],int n)
{//插入排序---将无序部分的任一元插入到有序部分的正确位置上
int i,j;
Key temp;
for(i=0;i //依次插入记录L[0]...L[n-1]
{
temp=L[i]; //temp是监视哨
j=i-1;
while(temp.Date //查找适合L[i]的插入位置
L[j+1]=L[j--]; //将记录关键字大于L[i].Date的纪录后移
L[j+1]=temp; //将记录L[i]插入到有序表的合适位置上
}
return ;
}
void paixu::BubbleSort(Key L[],int n)
{//冒泡排序算法
int i,j,temp;
for(i=0;i //外循环
{
for(j=i;j //内循环
{
if(L[i].Date>L[j].Date) //从第一个数据开始依次与其后面的数相比,若大则交换
{
temp=L[i].Date;
L[i].Date=L[j].Date;
L[j].Date=temp;
}
}
}
return;
}
void paixu::merge(Key L[], int low, int m, int high)
{//两相邻的有序表(一个从low到m;另一个从m+1到high)合并为一个有序表(从low到high)
Key r[MAX]; //合并时用的缓冲向量
int i, j, k;
i = low;
j = m + 1;
k = 0;
while(i <= m && j <= high) //两相邻的有序表合并
if(L[i].Date <= L[j].Date)
{r[k] = L[i]; i++; k++;}
else
{r[k] = L[j]; j++; k++;}
while(i <= m) //有序表剩余部分处理
{r[k] = L[i]; i++; k++;}
while(j <= high) //有序表剩余部分处理
{r[k] = L[j]; j++; k++;}
for(i = low, k = 0; i <= high; i++, k++)//缓冲向量r复制到原来的r中
L[i] = r[k];
}
void paixu::merge_one(Key L[], int lenth, int n)
{//二路归并中的"一趟归并"算法
int i = 0;
while(i + 2 * lenth - 1 < n)
{merge(L, i, i + lenth - 1, i + 2 * lenth - 1);//两子序列长度相等的
i = i + 2 * lenth;} //情况下调用merge
if(i + lenth - 1 < n - 1)
merge(L, i, i + lenth - 1, n - 1); //序列中的余留部分处理
}
void paixu::mergesort(Key L[], int n)
{//二路归并排序算法
int lenth = 1; //有序子序列长度初始值 = 1
while(lenth < n)
{
merge_one(L, lenth, n); //调用"一趟归并"的算法
lenth = 2 * lenth; //有序子序列长度加倍
}
}
void paixu::ShellSort(Key L[],int n)
{//希尔排序---取增量d(i+1)=d(i)/2的希尔排序算法
int i,h,p,temp,m; //p为交换标志,h为增量步长
h=n;
while(h>0)
{
h=h/2; //取步长为d(i+1)=d(i)/2
do{
p=0; //设置交换标志,p=0表示未交换
for(i=0;i
{
m=i+h; //取本趟的增量
if(L[i].Date>L[m].Date) //记录交换
{
temp=L[m].Date;
L[m].Date=L[i].Date;
L[i].Date=temp;
p=1; //p=1表示有交换
}
}
}while(p==1); //当p=0时,终止本趟排序
} //当增量h=1且p=0时终止算法
}
int paixu::partition(Key L[],int s,int t)
{//快速排序---快速排序算法中的一趟划分函数
//对无序区间L[s]到L[t]进行划分
int i,j;
Key temp;
i=s;j=t;temp=L[i]; //初始化,temp为基准记录
do{
while((L[j].Date>=temp.Date)&&(i
j--; //从右往左扫描查找第一个关键字小于temp的纪录
if(i
L[i++]=L[j]; //交换r[i]和r[j]
while((L[i].Date<=temp.Date)&&(i
i++; //从左往右扫描查找第一个关键字大于temp的纪录
if(i
L[j--]=L[i];
}while(i!=j); //i=j,则一次划分结束,基准记录到达最终位置
L[i]=temp; //最后将基准记录temp定位
return (i);
}
void paixu::QuickSort(Key L[], int first, int last)
{//快速排序
int i;
if(first < last)
{
i = partition(L, first, last); //一趟快速排序,返回i,产生了两个独立的待排子序列
QuickSort(L, first, i - 1); //对两个独立的待排子序列分别递归调用快速排序算法
QuickSort(L, i + 1,last);
}
return;
}
void paixu::sift(Key L[], int i, int m)
{//i是根结点编号,m是以i结点为根的子树中最后一个结点的编号
int j;
Key temp;
temp = L[i];
j = 2 * i; //j为i根结点的左孩子
while(j <= m)
{if(j < m && (L[j].Date
j++; //当i结点有左右孩子时,j取关键字大的孩子结点编号
if(temp.Date < L[j].Date)
{ L[i] = L[j]; i = j; j = 2 * i;}//按堆定义调整,并向下一层筛选调整
else break; //筛选调整完成,跳出循环
}
L[i] = temp;
}
void paixu::HeapSort(Key L[], int n)
{//堆排序: n为L表中记录数,从L[1]开始放起
int i;
Key temp;
for(i = n/2; i >= 0; i--)
sift(L, i, n); //将无序序列建成大堆
for(i = n-1; i >= 1; i--)
{temp = L[0]; //堆顶及堆尾元素交换
L[0] = L[i];
L[i] = temp;
sift(L,0,i - 1); //交换后,从第一个元素开始调整为大堆,每次记录个数少一个
}
}
//其他需要的函数
void paixu::createA(int n)
{
int j, k;
cout<<"输入待排序数据(整数,以空格隔开,0 结束) : "<<endl;
k=0;
cin>>j;
while(j != 0) //将整数存放到数组S中
{
S[k].Date=j;
k++;
cin>>j;
}
s1=S;
}
void paixu::createrandnum(int a[],int n)
{//产生随机整数
int i;
srand((int)time(0)); //产生随机数的种子
for(i=0;i
a[i]=rand()$0; //产生的是240以下的随机数
cout<<" 排序前原始随机数据"<<endl;
for(i=0;i
{
cout<<" "<<a[i];
if(i==0)
cout<<endl;
}
cout<<endl;
}
void paixu::createB(int n)
{//产生n个随机整数,并保存到记录数组S中
int b[MAX];
int i;
createrandnum(b,n);
for(i=0;i
S[i].Date=b[i]; //将随机整数存放到数组S中
s1=S;
}
void paixu::frontdisplayList(Key L[], int n)
{//显示未排数据
int i;
printf("\n排序前 : ");
for (i = 0; i < n; i++)
printf(" %d",L[i].Date);
printf("\n\n");
}
void paixu::reardisplayList(Key L[], int n)
{//显示已排数据
int i;
printf("排序后 : ");
for (i = 0; i < n; i++)
printf(" %d",L[i].Date);
printf("\n\n");
}
void paixu::face1()
{//欢迎界面
cout<<endl<<endl;
cout<<"\t\t 欢迎进入本系统!"<<endl;
cout<<"\t\t 本系统为排序算法比较!"<<endl<<endl<<endl<<endl;
cout<<"\t\t 请按任意键继续。。。。。。。。。。"<<endl;
getch();
system("cls");
}
char paixu::choose()
{//选择数据产生方式
char i;
cout<<endl<<endl<<"请选择产生数组方式(数据最大个数为200):"<<endl;
cout<<" A:选择键盘输入产生数组"<<endl;
cout<<" B:选择随机产生数组"<<endl<<endl;
cout<<" 请输入你的选择: ";
cin>>i;
return i;
}
void paixu::meun()
{//选择排序算法
char * string[]={"",
"\t ",
"\t 操作方法:(请输入以下数字进行!) ",
"\t ",
"\t --------排序算法的比较---------- ",
"\t 1----选择排序 ",
"\t 2----插入排序 ",
"\t 3----冒泡排序 ",
"\t 4----二路归并排序 ",
"\t 5----希尔排序 ",
"\t 6----快速排序 ",
"\t 7----堆排序 ",
"\t 8----请屏 ",
"\t 0----退出 "};
for(int i=14;i>0;i--)
{
system("cls");
for(int j=i;j<14;j++)
cout<<string[j]<<endl;
}
}
void paixu::face2()
{//欢迎推出界面
char * string[]={
"\t ┃ 谢谢你的使用! ┃",
"\t ┃ 欢迎下次登陆! ┃"
};
for(int i=0;i<2;i++)
{
cout<<string[i]<<endl;
}
cout<<endl<<endl;
}
void main()
{
int k,n;
char c;
paixu a;
a.face1();
for(;;)
{
c=a.choose();
if(c=='A'||c=='a')
{
cout<<"输入个数:"<<endl;
cin>>n;
a.createA(n);break;
}
if(c=='B'||c=='b')
{
cout<<"产生多少个数:"<<endl;
cin>>n;
a.createB(n);break;
}
else
{
cout<<"选择错误"<<endl;
continue;
}
}
a.meun();
a.frontdisplayList(s1,n);
for(;;)
{
cout<<"\t请按数字(0-8)键选择功能"<<endl;
cin>>k;
switch(k)
{
case 1:
{
cout<<"选择排序排序"<<endl;
a.SelectSort(s1,n);
a.reardisplayList(s1,n);break;
}
case 2:
{
cout<<"插入排序"<<endl;
a.InsertSort(s1,n);
a.reardisplayList(s1,n);break;
}
case 3:
{
cout<<"冒泡排序"<<endl;
a.BubbleSort(s1,n);
a.reardisplayList(s1,n);break;
}
case 4:
{
cout<<"二路归并排序"<<endl;
a.mergesort(s1,n);
a.reardisplayList(s1,n);break;
}
case 5:
{
cout<<"希尔排序"<<endl;
a.ShellSort(s1,n);
a.reardisplayList(s1,n);break;
}
case 6:
{
cout<<"快速排序"<<endl;
a.QuickSort(s1,0,n-1);
a.reardisplayList(s1,n);break;
}
case 7:
{
cout<<"堆排序"<<endl;
a.HeapSort(s1,n);
a.reardisplayList(s1,n);break;
}
case 8:{ system("cls");a.meun();break; }
case 0: {system("cls");a.face2();exit(0);}
default:
cout<<"\t输入错误"<<endl;
}
}
}