資料結構實驗課_實驗八 排序
技術標籤:資料結構實驗課lsr
一.實驗內容
1.編寫程式實現下列排序演算法:
(1)插入排序;
(2)希爾排序;
(3)氣泡排序;
(4)快速排序;
(5)選擇排序;
(6)堆排序;
(7)歸併排序。
2.在主函式中設計一個簡單的選單,用隨機函式生成一組數,分別測試上述演算法。
程式碼實現:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<Windows.h>
typedef int keytype;
typedef struct {
keytype key;/*關鍵字碼*/
}RecType;
int s[50][2];/*輔助棧s*/
void PrintArray(RecType R[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%6d",R[i].key);
printf("\n");
}
void InsertSort(RecType R[],int n)/*用直接插入排序法對R[n]進行排序*/
{
int i,j;
RecType temp;
for (i=0;i<=n-2;i++)
{
temp=R[i+1];
j=i;
while (temp.key<=R[j].key && j>-1)
{
R[j+1]=R[j];
j--;
}
R[j+1]=temp;
}
}
void ShellInsert(RecType *r,int dk,int n)
{
int i,j;
keytype temp;
for(i=dk; i< n; ++i )
if(r[i].key <r[i-dk].key ) //將r[i]插入有序子表
{
temp=r[i].key;
r[i].key=r[i-dk].key;
for(j=i-2*dk;j>-1 && temp<r[j].key; j-=dk )
r[j+dk].key=r[j].key; // 記錄後移
r[j+dk].key = temp; // 插入到正確位置
}
}
void ShellSort(RecType *L,int dlta[],int t,int n)/*希爾排序*/
{
// 按增量序列 dlta[t-1] 對順序表L作希爾排序
int k;
for(k=0;k<t;k++)
ShellInsert(L,dlta[k],n); //一趟增量為 dlta[k] 的插入排序
} // ShellSort
void CreatArray(RecType R[],int n)
{
int i;
Sleep(1000);
srand( (unsigned)time( NULL ) );
for(i=0;i<n;i++)
R[i].key=rand()%1000;
}
void BubbleSort(RecType R[],int n) /*氣泡排序*/
{
int i,j,flag;
keytype temp;
for(i=0;i<n-1;i++)
{
flag=0;
for(j=0;j<n-i-1;j++)
{
if(R[j].key>R[j+1].key)
{
temp=R[j].key;
R[j].key=R[j+1].key;
R[j+1].key=temp;
flag=1;
}
}
if(flag==0)break;
}
}
int Hoare(RecType r[],int l,int h)/*快速排序分割槽處理*/
{
int i,j;
RecType x;
i=l;j=h;x=r[i];
do{
while(i<j && r[j].key>=x.key)j--;
if(i<j)
{
r[i]=r[j];
i++;
}
while(i<j && r[i].key<=x.key)i++;
if (i<j)
{
r[j]=r[i];
j--;
}
}while(i<j);
r[i]=x;
return(i);
} /*Hoare*/
void QuickSort1(RecType r[],int n) /*快速排序非遞迴*/
{
int l=0,h=n-1,tag=1,top=0,i;
do{
while (l<h)
{
i=Hoare(r,l,h);
top++;
s[top][0]=i+1;
s[top][1]=h;
h=i-1;
}/*tag=0表示棧空*/
if (top==0)tag=0;
else
{
l=s[top][0];h=s[top][1];top--;
}
}while (tag==1); /*棧不空繼續迴圈*/
} /*QuickSort1*/
void SelectSort(RecType R[],int n)/*直接選擇排序*/
{
int i,j,k; RecType temp;
for(i=0;i<n-1;i++)
{
k=i;/*設第i個記錄關鍵字最小*/
for(j=i+1;j<n;j++)/*查詢關鍵字最小的記錄*/
if(R[j].key<R[k].key)
k=j;/*記住最小記錄的位置*/
if (k!=i) /*當最小記錄的位置不為i時進行交換*/
{
temp=R[k];
R[k]=R[i];
R[i]=temp;
}
}
}
void HeapAdjust(RecType R[],int l,int m)/*堆排序篩選*/
{/*l表示開始篩選的結點,m表示待排序的記錄個數。*/
int i,j;
RecType temp;
i=l;
j=2*i+1; /*計算R[i]的左孩子位置*/
temp=R[i]; /*將R[i]儲存在臨時單元中*/
while(j<=m-1)
{
if(j<m-1 && R[j].key<R[j+1].key)
j++; /*選擇左右孩子中最大者,即右孩子*/
if(temp.key<R[j].key)/*當前結點小於左右孩子的最小者*/
{
R[i]=R[j];i=j;j=2*i+1;
}
else /*當前結點不小於左右孩子*/
break;
}
R[i]=temp;
}
void HeapSort(RecType R[],int n)/*堆排序*/
{
int j;
RecType temp;
for(j=n/2-1;j>=0;j--) /*構建初始堆*/
HeapAdjust(R,j,n);/*呼叫篩選演算法*/
for(j=n;j>1;j--) /*將堆頂記錄與堆中最後一個記錄交換*/
{
temp=R[0];
R[0]=R[j-1];
R[j-1]=temp;
HeapAdjust(R,0,j-1);/*將R[0..j-1]調整為堆*/
}
}
void Merge(RecType aa[],RecType bb[],int l,int m,int n)
{/*將兩個有序子序列aa[1…m]和aa[m+1,…n]合併為一個有序序列bb[1…n]*/
int i,j,k;
k=l;i=l;j=m+1;/*將i,j,k分別指向aa[1…m]、aa[m+1,…n]、bb[1…n]首記錄*/
while (i<=m && j<=n) /*將aa中記錄由小到大放入bb中*/
if(aa[i].key<=aa[j].key)
bb[k++]=aa[i++];
else
bb[k++]=aa[j++];
while (j<=n) /*將剩餘的aa[j…n]複製到bb中*/
bb[k++]=aa[j++];
while (i<=m) /*將剩餘的aa[i…m]複製到bb中*/
bb[k++]=aa[i++];
}
void MergeOne(RecType aa[],RecType bb[],int len,int n)
{/*從aa[1…n]]歸併到bb[1…n],其中len是本趟歸併中有序表的長度*/
int i;
for(i=0;i+2*len-1<=n;i=i+2*len)
Merge(aa,bb,i,i+len-1,i+2*len-1);/*對兩個長度為len的有序表合併*/
if(i+len-1<n) /*當剩下的元素個數大於一個子序列長度len時*/
Merge(aa,bb,i,i+len-1,n);
else /*當剩下的元素個數小於或等於一個子序列長度len時*/
Merge(aa,bb,i,n,n); /*複製剩下的元素到bb中*/
}
void MergeSort(RecType aa[],RecType bb[],int n)//歸併排序
{
int len=1; /*len是排序序列表的長度 */
while (len<n)
{
MergeOne(aa,bb,len,n-1);
MergeOne(bb,aa,2*len,n-1);
len=4*len;
}
}
int main()
{
int n,data[3]={4,2,1},cord;
RecType *r,*bb;
printf("Please input number:");
scanf("%d",&n);
r=(RecType *)malloc(sizeof(RecType)*n);
bb=(RecType *)malloc(sizeof(RecType)*n);
memset(bb,0,sizeof(RecType)*n);
do
{
printf("\n 主選單 \n");
printf("1----插入排序\n");
printf("2----希爾排序\n");
printf("3----氣泡排序\n");
printf("4----快速排序\n");
printf("5----選擇排序\n");
printf("6----堆排序\n");
printf("7----歸併排序\n");
printf("8----退出\n");
scanf("%d",&cord);
switch(cord)
{
case 1:
memset(r,0,sizeof(RecType)*n);
CreatArray(r,n);
PrintArray(r,n);
InsertSort(r,n);
PrintArray(r,n);
break;
case 2:
memset(r,0,sizeof(RecType)*n);
CreatArray(r,n);
PrintArray(r,n);
ShellSort(r,data,3,n);
PrintArray(r,n);
break;
case 3:
memset(r,0,sizeof(RecType)*n);
CreatArray(r,n);
PrintArray(r,n);
BubbleSort(r,n);
PrintArray(r,n);
break;
case 4:
memset(r,0,sizeof(RecType)*n);
CreatArray(r,n);
PrintArray(r,n);
QuickSort1(r,n);
PrintArray(r,n);
break;
case 5:
memset(r,0,sizeof(RecType)*n);
CreatArray(r,n);
PrintArray(r,n);
SelectSort(r,n);
PrintArray(r,n);
break;
case 6:
memset(r,0,sizeof(RecType)*n);
CreatArray(r,n);
PrintArray(r,n);
HeapSort(r,n);
PrintArray(r,n);
break;
case 7:
memset(r,0,sizeof(RecType)*n);
CreatArray(r,n);
PrintArray(r,n);
MergeSort(r,bb,n);
PrintArray(r,n);
break;
case 8:
exit(0);
default:
cord=0;
}
}while(cord<=8);
return 0;
}
程式演示:
Please input number:6
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出
1
885 785 888 182 437 260
182 260 437 785 885 888
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出
2
917 965 690 439 279 759
279 439 690 759 917 965
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出
3
927 442 746 325 454 771
325 442 454 746 771 927
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出
4
933 939 706 684 84 625
84 625 684 706 933 939
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出
5
940 668 667 274 945 478
274 478 667 668 940 945
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出
6
947 397 627 633 806 332
332 397 627 633 806 947
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出
7
953 894 587 224 435 417
224 417 435 587 894 953
主選單
1----插入排序
2----希爾排序
3----氣泡排序
4----快速排序
5----選擇排序
6----堆排序
7----歸併排序
8----退出