#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define MAXSIZE 20//一个用作示例的小顺序表的最大长度
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERLOW -2
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)< (b))
#define LQ(a,b) ((a)<=(b))
typedef int Status;
typedef int KeyType;
typedef struct
{//记录类型(学生学号及姓名)
KeyType key;
char name[10];
}RedType;
typedef struct
{//顺序表存储结构
RedType *elem;//elem[0]闲置或用作哨兵单元
int length;//顺序表示实际长度
}SqList;
Status InitSqList(SqList &L)
{//初始化顺序表
L.elem=(RedType *)malloc((MAXSIZE+1)*sizeof(RedType));
L.length=0;
return OK;
}
Status CreateSqList(SqList &L,int n)
{//构建顺序表
int i;
printf("请输入各条记录的内容(学号、姓名):/n");
for(i=1;i<=n;i++)
scanf("%d%s",&L.elem[i].key,L.elem[i].name);
L.length=n;
return OK;
}
void Print(SqList L)
{//依次输出顺序表中各记录
int i;
for(i=1;i<=L.length;i++)
printf("%d%s/n",L.elem[i].key,L.elem[i].name);
}
void InsertSort(SqList &L)
{//对顺序表直接插入排序
int i,j;
for(i=2;i<=L.length;i++)
if(LT(L.elem[i].key,L.elem[i-1].key))
{
L.elem[0]=L.elem[i];
for(j=i-1;LT(L.elem[0].key,L.elem[j].key);j--)
L.elem[j+1]=L.elem[j];
L.elem[j+1]=L.elem[0];
}
}
void BInsertSort(SqList &L)
{//折半插入排序
int i,j,low,high,mid;
for(i=2;i<=L.length;i++)
{//执行n-1次直接插入排序
L.elem[0]=L.elem[i];
low=1;high=i-1;
while(low<=high)//查找插入位置(high的后面)
{
mid=(low+high)/2;
if(LT(L.elem[0].key,L.elem[mid].key))
high=mid-1;
else
low=mid+1;
}
for(j=i-1;j>=high+1;j--)
L.elem[j+1]=L.elem[j];
L.elem[high+1]=L.elem[0];
}
}
void ShellInsert(SqList &L,int dk)
{//一趟希尔插入排序(等价于步长为dk的直接插入排序)
int i,j;
for(i=1+dk;i<=L.length;i++)
if(LT(L.elem[i].key,L.elem[i-1].key))
{
L.elem[0]=L.elem[i];
for(j=i-dk;LT(L.elem[0].key,L.elem[j].key);j-=dk)
L.elem[j+dk]=L.elem[j];
L.elem[j+dk]=L.elem[0];
}
}
void ShellSort(SqList &L)
{//希尔排序
int t=3,dlta[3]={5,3,1},k;
for(k=0;k<t;k++)
ShellInsert(L,dlta[k]);
}
int Partition(SqList &L,int low,int high)
{//求顺序表L.elem[low...high]的枢轴记录在表中的位置
int pivotkey;
pivotkey=L.elem[low].key;
L.elem[0]=L.elem[low];
while(low<high)
{//四种情况
while((low<high)&&LQ(pivotkey,L.elem[high].key)) high--;
L.elem[low]=L.elem[high];
while((low<high)&&LQ(L.elem[low].key,pivotkey)) low++;
L.elem[high]=L.elem[low];
}
L.elem[low]=L.elem[0];
return low;
}
void QSort(SqList &L,int low,int high)
{//对顺序表L中的子序列L.elem[low...high]做快速排序
int pivotloc;//枢轴记录在顺序表中的位置
if(low<high)
{
pivotloc=Partition(L,low,high);
QSort(L,low,pivotloc-1);
QSort(L,pivotloc+1,high);
}
}
void QuickSort(SqList &L)
{
QSort(L,1,L.length);
}
void Merge(RedType SR[],RedType TR[],int i,int m,int n)
{
int j,k,l;
for(j=m+1,k=i;i<=m&&j<=n;++k)
if(LQ(SR[i].key,SR[j].key))
TR[k]=SR[i++];
else
TR[k]=SR[j++];
if(i<=m)
for(l=0;l<=m-i;l++)
TR[k+1]=SR[i+1];
if(j<=n)
for(l=0;l<=n-j;l++)
TR[k+1]=SR[j+1];
}
void MSort(RedType SR[],RedType TR1[],int s,int t)
{//将SR[]归并排序为TR1[]
int m;
RedType TR2[MAXSIZE+1];
if(s==t)
TR1[s]=SR[s];
else
{
m=(s+t)/2;
MSort(SR,TR2,s,m);
MSort(SR,TR2,m+1,t);
Merge(TR2,TR1,s,m,t);
}
}
void MergeSort(SqList &L)
{
MSort(L.elem,L.elem,1,L.length);
}
int Choice()
{//选择排序方法
int num;
printf("1.直接插入排序/n2.折半插入排序/n3.希尔排序/n4.快速排序/n5.归并排序/n请输入您选择的排序编号:");
scanf("%d",&num);
return num;
}
int main()
{
SqList L;
int n;
InitSqList(L);
printf("请输入要排序的顺序表的长度:");scanf("%d",&n);
CreateSqList(L,n);
printf("***您输入的记录序列是***/n");Print(L);
switch(Choice())
{
case 1:InsertSort(L);printf("**经过直接插入排序后生成的记录序列是**/n");Print(L);break;
case 2:BInsertSort(L);printf("**经过折半插入排序后生成的记录序列是**/n");Print(L);break;
case 3:ShellSort(L);printf("**经过希尔排序后生成的记录序列是**/n");Print(L);break;
case 4:QuickSort(L);printf("**经过快速排序后生成的记录序列是**/n");Print(L);break;
case 5:MergeSort(L);printf("**经过归并排序后生成的记录序列是**/n");Print(L);break;
default:break;
}
return 0;
}