/*
第十章 内排序 上机实验
实验目的:熟悉掌握插入排序、交换排序和选择排序的思想和方法实现。
实验要求
设有一组记录{38,'b'},{65,'c'},{49,'a'},{97,'d'},{76,'e'},{13,'f'},{27,'g'},{49,'h'},其中每个记录第一个域的数字表示关键字,第二个域的字母表示记录信息。请按照关键字从小到大对记录进行排序,具体要求如下:
(1)实现直接插入排序,完成函数InsertSort,并输出每一次插入完成后顺序表中的记录,可以使用工程中的print函数进行输出;
(2)实现折半插入排序,完成函数BInsertSort,输出最后的排序结果;
(3)实现希尔排序,增量序列为dt={5,3,1},完成函数ShellInsert,ShellSort,并输出每一趟希尔插入排序之后的结果;
(4)实现快速排序,完成函数Partition,QSort和QuickSort,输出每一趟Partition之后的记录结果;
(5)实现选择排序,输出输出每一趟记录和最后的排序结果;
(6)比较不同算法中关键字相同的两个记录a与h在排序后的相对位置变化。
*/
#include<stdio.h>
#define MAXSIZE 20
typedef int KeyType;
typedef struct
{
KeyType key;
char name;
}RedType;
typedef struct
{
RedType r[MAXSIZE+1];//r[0]闲置或用作哨兵
int length;
}SqList;
//补.创建顺序表
void CreateList(SqList *L,RedType a[],int n)
{
int i;
for(i=1;i<=n;i++)
(*L).r[i]=a[i-1];//直接把结构体类型数据赋给顺序表
(*L).length=n;
}
//补.遍历
void PrintList(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("{%d,'%c'}",L.r[i].key,L.r[i].name);
}
//算法8.1直接插入排序
void InsertSort(SqList *L)
{
int i,j;
for(i=2;i<=(*L).length;i++)//从第二个开始,把每一个元素插入到已排好的序列,直到最后一个
if((*L).r[i].key<(*L).r[i-1].key)//如果下一个比上一个小,则执行语句。若下一个大于或等于上一个,则直接进入下一轮循环,不需插入
{
(*L).r[0]=(*L).r[i];//r[0]为哨兵
(*L).r[i]=(*L).r[i-1];//把r[r-1]移动到第r个位置
for(j=i-2;(*L).r[0].key<(*L).r[j].key;--j)//从后向前寻找插入的位置
(*L).r[j+1]=(*L).r[j];//记录逐个后移,直到找到插入的位置
(*L).r[j+1]=(*L).r[0];//将r[i]插入到正确位置
}
}
//直接插入排序,按步骤输出每次排序的结果
void InsertSort_steps(SqList *L)
{
int i,j;
for(i=2;i<=(*L).length;i++)//从第二个开始,把每一个元素插入到已排好的序列,直到最后一个
{
if((*L).r[i].key<(*L).r[i-1].key)//如果下一个比上一个小,则执行语句。若下一个大于或等于上一个,则直接进入下一轮循环
{
(*L).r[0]=(*L).r[i];//r[0]为哨兵
(*L).r[i]=(*L).r[i-1];//把r[r-1]移动到第r个位置
for(j=i-2;(*L).r[0].key<(*L).r[j].key;--j)//从后向前寻找插入的位置
(*L).r[j+1]=(*L).r[j];//记录逐个后移,直到找到插入的位置
(*L).r[j+1]=(*L).r[0];//将r[i]插入到正确位置
}
printf("第%d次插入:",i-1);
PrintList((*L));
printf("\n");
}
}
//算法8.2折半插入排序
//折半插入排序也是插入排序,它与直接插入排序不同的是,寻找插入位置的方法不同
void BInsertSort(SqList *L)
{
int i,j,low,high,m;
for(i=2;i<=(*L).length;++i)//从第二个开始,把每一个元素插入到已排好的序列,直到最后一个
{
(*L).r[0]=(*L).r[i];
low=1;high=i-1;
while(low<=high)
{
m=(low+high)/2;
if((*L).r[0].key<(*L).r[m].key) high=m-1;
else low=m+1;
}
for(j=i-1;j>=high+1;--j) (*L).r[j+1]=(*L).r[j];//记录逐个后移
(*L).r[high+1]=(*L).r[0];//将r[i]插入到正确位置
}
}
//折半插入排序,按步骤输出每次排序的结果
void BInsertSort_steps(SqList *L)
{
//虽然输出结果与直接插入排序结果形同,但是查找正确位置的时间变短了
int i,j,low,high,m;
for(i=2;i<=(*L).length;++i)//从第二个开始,把每一个元素插入到已排好的序列,直到最后一个
{
(*L).r[0]=(*L).r[i];
low=1;high=i-1;
while(low<=high)
{
m=(low+high)/2;
if((*L).r[0].key<(*L).r[m].key) high=m-1;
else low=m+1;
}
for(j=i-1;j>=high+1;--j) (*L).r[j+1]=(*L).r[j];//记录逐个后移
(*L).r[high+1]=(*L).r[0];//将r[i]插入到正确位置
printf("第%d次插入:",i-1);
PrintList((*L));
printf("\n");
}
}
//算法8.3希尔排序
void ShellInsert(SqList *L,int dk)
{
int i,j;
for(i=dk+1;i<(*L).length;i++)
if((*L).r[i].key<(*L).r[i-dk].key)
{
(*L).r[0]=(*L).r[i];
for(j=i-dk;j>0&&(*L).r[0].key<(*L).r[j].key;j-=dk)
(*L).r[j+dk]=(*L).r[j];
(*L).r[j+dk]=(*L).r[0];
}
}
void ShellSort(SqList *L,int dt[],int t)
{
int k;
for(k=0;k<t;++k)
ShellInsert(&(*L),dt[k]);
}
//希尔插入排序,按步骤输出每次排序的结果
void ShellSort_steps(SqList *L,int dt[],int t)
{
int k;
for(k=0;k<t;++k)
{
ShellInsert(&(*L),dt[k]);
printf("第%d趟排序:",k+1);
PrintList((*L));
printf("\n");
}
}
//算法8.5快速牌序
//设枢纽关键字,把小于关键字的放在左边,大于关键字的放在右边,递归调用。
int Partition(SqList *L,int low,int high)
{
//返回枢纽位置,并把小于关键字的放在枢纽左边,大于关键字的放在枢纽右边
KeyType pivotkey;
(*L).r[0]=(*L).r[low];//做枢纽记录
pivotkey=(*L).r[low].key;//枢纽的关键字保存在pivotkey中
while(low<high)
{
while(low<high&&(*L).r[high].key>=pivotkey) --high;
(*L).r[low]=(*L).r[high];
while(low<high&&(*L).r[low].key<=pivotkey) ++low;
(*L).r[high]=(*L).r[low];
}
(*L).r[low]=(*L).r[0];
return low;
}
void QSort(SqList *L,int low,int 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);
}
//快速排序,按步骤输出每次排序的结果
int count=1;
void QSort_steps(SqList *L,int low,int high)
{
int pivotloc;
if(low<high)
{
pivotloc=Partition(&(*L),low,high);
printf("\n第%d次排序为:",count++);
PrintList(*L);
QSort_steps(&(*L),low,pivotloc-1);
QSort_steps(&(*L),pivotloc+1,high);
}
}
void QuickSort_steps(SqList *L)
{
QSort_steps(&(*L),1,(*L).length);
}
//算法8.6简单选择排序
void SelectSort(SqList *L)
{
int i,j,k;
RedType t;
for(i=1;i<(*L).length;++i)
{
k=i;
for(j=i+1;j<=(*L).length;++j)
if((*L).r[j].key<(*L).r[k].key) k=j;
if(k!=i)
{
t=(*L).r[i];(*L).r[i]=(*L).r[k];(*L).r[k]=t;
}
}
}
//简单选择排序,按步骤输出每次排序结果
void SelectSort_steps(SqList *L)
{
int i,j,k;
RedType t;
for(i=1;i<(*L).length;++i)
{
k=i;
for(j=i+1;j<=(*L).length;++j)
if((*L).r[j].key<(*L).r[k].key) k=j;
if(k!=i)
{
t=(*L).r[i];(*L).r[i]=(*L).r[k];(*L).r[k]=t;
}
printf("\n第%d次排序为:",i);
PrintList(*L);
}
}
int main()
{
SqList L;
RedType a[8]={{49,'a'},{38,'b'},{65,'c'},{97,'d'},{76,'e'},{13,'f'},{27,'g'},{49,'h'}};
//************************************************
CreateList(&L,a,8);
InsertSort(&L);
printf("直接插入排序后,最终结果是:");
PrintList(L);
printf("\n");
CreateList(&L,a,8);
printf("直接插入排序的过程:\n");
InsertSort_steps(&L);
printf("\n\n");
//************************************************
CreateList(&L,a,8);
BInsertSort(&L);
printf("折半插入排序后,最终结果是:");
PrintList(L);
printf("\n");
CreateList(&L,a,8);
printf("折半插入排序的过程:\n");
BInsertSort_steps(&L);
printf("\n\n");
//************************************************
CreateList(&L,a,8);
int dt[3]={5,3,1};
ShellSort(&L,dt,3);
printf("希尔排序后,最终结果是:");
PrintList(L);
printf("\n");
CreateList(&L,a,8);
printf("希尔排序的过程(增量为%d,%d,%d):\n",dt[0],dt[1],dt[2]);
ShellSort_steps(&L,dt,3);
printf("\n\n");
//************************************************
CreateList(&L,a,8);
QuickSort(&L);
printf("快速排序后,最终结果是:");
PrintList(L);
CreateList(&L,a,8);
printf("\n快速排序的过程:");
QuickSort_steps(&L);
printf("\n\n");
//************************************************
CreateList(&L,a,8);
SelectSort(&L);
printf("\n简单选择排序后,最终结果是:");
PrintList(L);
CreateList(&L,a,8);
printf("\n简单选择排序的过程:");
SelectSort_steps(&L);
printf("\n\n");
//************************************************
return 0;
}
【数据结构C语言】排序
最新推荐文章于 2024-07-31 13:43:08 发布