一、操作要求
1.输入同样一组整型数据,作为待排序记录的关键字序列。
2.在进行直接插入排序、冒泡排序、简单选择排序的同时统计在排序过程中对关键字的比较次数和移动次数,并分别输出排序前的数据序列和排序后的数据序列及其统计结果。
3.在进行希尔排序、快速排序和归并排序的同时统计在排序过程中对关键字的比较次数和移动次数,并分别输出排序前的数据序列和排序后的数据序列及其统计结果。
4.在主程序中设计一个菜单,使用户可选择执行其中的任何一种或几种排序,并查看排序结果。
二、代码实现
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define MAXSIZE 100
#define OK 1
typedef int status;
typedef int KeyType;
typedef int InfoType;
typedef struct{
KeyType key;
InfoType otherinfo;
}RecdType;
typedef struct{
RecdType r[MAXSIZE+1];
int length;
}SqList;
struct{
int cpn;
int mvn;
}cm[6];
status CreateList(SqList &L,int n){
L.length=n;
int i;
for(i=1;i<=L.length;i++)
scanf("%d",&L.r[i].key);
return OK;
}//创建一个长度为n的待排序顺序表
void Insert(SqList &L){
int i,j;
for(i=2;i<=L.length;i++)
if(cm[1].cpn++,L.r[i].key<L.r[i-1].key){
L.r[0]=L.r[i];
cm[1].mvn++;
L.r[i]=L.r[i-1];
cm[1].mvn++;
for(j=i-2;cm[1].cpn++,L.r[0].key<L.r[j].key;j--){
L.r[j+1]=L.r[j];
cm[1].mvn++;
}
L.r[j+1]=L.r[0];
cm[1].mvn++;
}
} //直接插入排序
void Bubble(SqList &L){
int i,j,change;
RecdType temp;
change=1;
for(i=L.length;i>1;i--){
change=0;
for(j=1;j<i;j++)
if(cm[2].cpn++,L.r[j].key>L.r[j+1].key){
temp=L.r[j];
L.r[j]=L.r[j+1];
L.r[j+1]=temp;
change=1;
cm[2].mvn+=3;
}
}
}//冒泡排序
void Select(SqList &L){
int i,j,min;
for(i=1;i<L.length;i++){
min=i;
for(j=i+1;j<=L.length;++j){
if(cm[3].cpn++,L.r[j].key<L.r[min].key)
min=j;
}
if(min!=i){
RecdType temp=L.r[i];
L.r[i]=L.r[min];
L.r[min]=temp;
cm[3].mvn+=3;
}
}
}//简单选择排序
void Shell(SqList &L,int dk){
int i,j;
for(i=1+dk;i<=L.length;i++)
if(cm[4].cpn++,L.r[i].key<L.r[i-dk].key){
L.r[0]=L.r[i];//设置监视哨
L.r[i]=L.r[i-dk];
cm[4].mvn+=2;
for(j=i-2*dk;cm[4].cpn++,j>0&&L.r[0].key<L.r[j].key;j=j-dk)
L.r[j+dk]=L.r[j];
cm[4].mvn++;
L.r[j+dk]=L.r[0];//将L.r[i]插入j+dk
cm[4].mvn++;
}
}//希尔排序
void s_Shell(SqList &L,int dlta[],int t){
for(int k=0;k<t;++k)
Shell(L,dlta[k]);
}// 按照增量dlta[0..t-1]对L做希尔排序
int partition(SqList &L,int low,int high){
L.r[0]=L.r[low];//设为枢轴
KeyType pivotkey=L.r[low].key;
cm[5].mvn++;
while(low<high){
while(low<high&&L.r[high].key>=pivotkey){
--high;
cm[5].cpn++;
}
if(low<high){
L.r[low++]=L.r[high];
cm[5].mvn++;
}
while(low<high&&L.r[low].key<=pivotkey){
++low;
cm[5].cpn++;
}
if(low<high){
L.r[high--]=L.r[low];
cm[5].mvn++;
}
}
L.r[low]=L.r[0];
cm[5].mvn++;
return low;
}//一趟快速排序
void sort(SqList &L,int low,int high){
if(low<high){
int pivotloc=partition(L,low,high);
sort(L,low,pivotloc-1);
sort(L,pivotloc+1,high);
}
} //递归形式快速排序
void quick(SqList &L){
sort(L,1,L.length);
}//顺序表快速排序
void Merge(RecdType SR[],RecdType TR[],int i,int m,int n){
//两个相邻有序表SR[i...m]与SR[m+1...n]归并为有序表TR[i...n]
int j=m+1,k=i;
while(i<=m&&j<=n){
if(cm[6].cpn++,SR[i].key<=SR[j].key){
TR[k++]=SR[i++];
cm[6].mvn++;
}
else {
TR[k++]=SR[j++];
cm[6].mvn++;
}
}
while(i<=m){
TR[k++]=SR[i++];
cm[6].mvn++;
}
while(j<=n) {
TR[k++]=SR[j++];
cm[6].mvn++;
}
}//两个有序序列的归并算法
void m_sort(RecdType SR[],RecdType TR1[],int s,int t){
RecdType TR2[MAXSIZE+1];
if(s==t)
TR1[s]=SR[s];
else{
int m=(s+t)/2;
m_sort(SR,TR2,s,m);//前部分递归为有序TR2[s...m]
m_sort(SR,TR2,m+1,t);//后部分递归为有序TR2[m+1...t]
Merge(TR2,TR1,s,m,t);//将TR2[s...m]与TR2[s...m]归并为有序表TR1[s...t]
}
} //将SR[s...t]归并排序为TR[s...t]
void sort_merge(SqList &L){
//对顺序表进行
m_sort(L.r,L.r,1,L.length);
} //2路归并排序
void OutList(SqList L){
for(int i=1;i<=L.length;i++)
printf("%d\t",L.r[i].key);
printf("\n");
}//输出
int main(){
SqList L,L1,L2,L3,L4,L5,L6;
int n,i,a,K=3;
int dlta[K]={5,3,1};
for(i=0;i<=6;i++){
cm[i].cpn=0;
cm[i].mvn=0;
}
while(1){
printf("-----选择功能-----\n");
printf("1--建立一个序列\n");
printf("2--直接插入排序\n");
printf("3--冒泡排序\n");
printf("4--简单选择排序\n");
printf("5--希尔排序\n");
printf("6--快速排序\n");
printf("7--归并排序\n");
printf("请选择需要执行的功能(1-7):\n");
scanf("%d",&a);
switch(a){
case 1:
printf("建立一个序列\n");
printf("请输入序列元素个数:\n");
scanf("%d",&n);
printf("请输入序列元素:\n");
CreateList(L, n);
printf("\n");
break;
case 2:
printf("--直接插入排序--\n");
printf("排序前的序列为:\n");
OutList(L);
L1=L;
Insert(L1);
printf("排序后的序列为:\n");
OutList(L1);
printf("移动次数为:%d,比较次数为:%d\n",cm[1].mvn,cm[1].cpn);
printf("\n");
break;
case 3:
printf("--冒泡排序--\n");
printf("排序前的序列为:\n");
OutList(L);
L2=L;
Bubble(L2);
printf("排序后的序列为:\n");
OutList(L2);
printf("移动次数为:%d,比较次数为:%d\n",cm[2].mvn,cm[2].cpn);
printf("\n");
break;
case 4:
printf("--简单选择排序--\n");
printf("排序前的序列为:\n");
OutList(L);
L3=L;
Select(L3);
printf("排序后的序列为:\n");
OutList(L3);
printf("移动次数为:%d,比较次数为:%d\n",cm[3].mvn,cm[3].cpn);
printf("\n");
break;
case 5:
printf("--希尔排序--\n");
printf("排序前的序列为:\n");
OutList(L);
L4=L;
s_Shell(L4,dlta,K);
printf("排序后的序列为:\n");
OutList(L4);
printf("移动次数为:%d,比较次数为:%d\n",cm[4].mvn,cm[4].cpn);
printf("\n");
break;
case 6:
printf("--快速排序--\n");
printf("排序前的序列为:\n");
OutList(L);
L5=L;
quick(L5);
printf("排序后的序列为:\n");
OutList(L5);
printf("移动次数为:%d,比较次数为:%d\n",cm[5].mvn,cm[5].cpn);
printf("\n");
break;
case 7:
printf("--归并排序--\n");
printf("排序前的序列为:\n");
OutList(L);
L6=L;
sort_merge(L6);
printf("排序后的序列为:\n");
OutList(L6);
printf("移动次数为:%d,比较次数为:%d\n",cm[6].mvn,cm[6].cpn);
printf("\n");
break;
default: break;
}
}
}
三、运行结果