#include<stdio.h>
#include <stdlib.h>
#define N 6
void SelectSort(int L[],int n); //选择排序
void InsertSort(int r[],int n); //插入排序
void BubbleSort(int r[],int n); //冒泡排序
void MergeSort( int r[],int r1[],int n); //归并排序
void main()
{
int i,a[N],b[N];
char c;
printf("输入个数:");
for(i=1;i<N;i++) //后面几种排序方法中用到的下标都从开始,故此处与其保持一致
scanf("%4d",&a[i]);
do
{
for(int i=0;i<80;i++)
printf("*");
printf("\t 1:选择排序法\n");
printf("\t 2:冒泡排序法\n");
printf("\t 3:插入排序法\n");
printf("\t 4:合并排序法\n");
printf("\t 5:退出\n");
printf("\t 请选择输入选项【\\2\\3\\4\\5】:\n");
do
{
c=getchar();
}while(c!='1'&&c!='2'&&c!='3'&&c!='4'&&c!='5');
switch(c)
{
case '1':SelectSort(a,N); break;
case '2':BubbleSort(a,N); break;
case '3':InsertSort(a,N); break;
case '4':MergeSort(a,b,N); break;
case '5':exit(0);
}
printf("按任意键返回主菜单:\n");
//getchar();
}while(1);
}
void SelectSort(int L[],int n) //简单选择排序
{
int i,j,k,t;
for(i=1;i<n;i++) //选择第i+1小的元素,并交换到位
{
j=i;
for(k=i+1;k<n;++k)
if (L[k]<L[j]) j=k; //L[j] 中存放的是第i+1小的元素
if(j!=i)
{ t=L[i]; //交换
L[i]=L[j];
L[j]=t;
}
}
for(i=1;i<N;i++)
printf("%4d",L[i]);
}
void InsertSort(int r[],int n) //插入排序
{ int i,j;
for(i=1;i<n-1;i++)
{ r[0]=r[i+1]; // r[0]: 监视哨
j=i;
while(r[0] <r[j])
{ r[j+1]=r[j]; //记录后移
j--;
}
r[j+1]= r[0]; // 插入
}
for(i=1;i<N;i++)
printf("%4d",r[i]);
}
void BubbleSort(int r[],int n) //冒泡排序
{ //int flag=1,i; //当flag为,则停止排序
int i;
for (int i=n;i>=2;i--) //i表示趟数,最多n-1趟
{
//flag=0; //开始时元素未交换
for(int j=1;j<i-1;j++) //一开始写了个"j<=i-1",花了半个多小时才发现错误
{
if(r[j]>r[j+1])
{
int t=r[j];
r[j]=r[j+1];
r[j+1]=t;
//flag=1; // 交换
}
//if(flag==0) return; //若无交换则停止退出循环
}
}
for(i=1;i<N;i++)
printf("%4d",r[i]);
}
void merge(int r[],int r1[],int low,int mid,int high)
//r[low]到r[mid]与r[mid+1]到r[high]是两个有序子文件
//本算法将其归并成一个有序子文件从r1[low]到r1[high]
{
int i=low; int j=mid+1; int k=low;
while ((i<=mid) && (j<=high))
if (r[i]<=r[j]) r1[k++]=r[i++];//取小者复制
else r1[k++]=r[j++];
while (i<=mid) r1[k++]=r[i++];//复制第一个文件剩余记录
while (j<=high) r1[k++]=r[j++];//复制第二个文件剩余记录
}
//对r进行一趟归并,结果放在r1中
void mergepass(int r[],int r1[],int n,int length)
// length是本趟归并的有序子文件的长度
{ int i=1,j; //指向第一对子文件起始点
while (i+2*length<=n)//待归并记录至少有两个长度为length的子文件
{ merge(r,r1,i,i+length-1,i+2*length-1);
i=i+2*length; //指向下一对子文件起始点
}
if (i+length<n)//剩下两个子文件,其中一个长度小于length
merge(r,r1,i,i+length-1,n-1);
else //子文件个数为奇数,将最后一个子文件复制到r1中
for (j=i;j<n;j++) r1[j]=r[j];
}
void MergeSort( int r[],int r1[],int n ) //归并排序
{
int length=1,i;
while (length<n)
{
mergepass(r,r1,n,length) ; // 一趟归并,结果在r1中
length=2*length; //区间扩大一倍
mergepass(r1,r,n,length) ; // 再次归并,结果在r中
length=2*length;
}
for(i=1;i<n;i++)
printf("%4d",r[i]);
}
参考资料:花了N个小时