1. 程式人生 > 其它 >資料結構實驗課_實驗八 排序

資料結構實驗課_實驗八 排序

技術標籤:資料結構實驗課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----退出