演算法與資料結構實驗六 內部排序
實驗專案名稱:實驗六 內部排序
一、 實驗目的
1.掌握插入排序的方法及效率分析
2.掌握選擇排序的方法及效率分析
3.掌握交換排序的方法及效率分析
4.掌握歸併排序的方法及效率分析
二、 實驗內容
6-4 快速排序
本題要求實現快速排序的一趟劃分函式,待排序列的長度1<=n<=1000。
函式介面定義:
int Partition ( SqList L, int low, int high );
其中L是待排序表,使排序後的資料從小到大排列。
###型別定義:
typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/
裁判測試程式樣例:
#include<stdio.h>#include<stdlib.h>typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;void CreatSqList(SqList *L);/*待排序列建立,由裁判實現,細節不表*/ int
輸入樣例:
第一行整數表示參與排序的關鍵字個數。第二行是關鍵字值 例如:
10
5 2 4 1 8 9 10 12 3 6
輸出樣例:
輸出由小到大的有序序列,每一個關鍵字之間由空格隔開,最後一個關鍵字後有一個空格。
1 2 3 4 5 6 8 9 10 12
6-5 堆排序
本題要求實現堆排序中的篩選函式,待排序列的長度1<=n<=1000。
函式介面定義:
void HeapAdjust( HeapType H, int s, int m);
其中L是待排序表,使排序後的資料從小到大排列。
###型別定義:
typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;typedef SqList HeapType;
裁判測試程式樣例:
#include<stdio.h>#include<stdlib.h>typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;typedef SqList HeapType; void CreatSqListHeapType *L);/*待排序列建立,由裁判實現,細節不表*/ void HeapAdjust( HeapType H, int s, int m);void HeapSort( HeapType H);int main(){ HeapType L; int i; CreatSqList(&L); HeapSort(L); for(i=1;i<=L.Length;i++) { printf("%d ",L.elem[i]); } return 0;}void HeapSort( HeapType H){ /*堆順序表H進行堆排序*/ int i; KeyType rc; /*建立初始堆*/ for( i=H.Length/2;i>0; i--) { HeapAdjust(H, i, H.Length); } for(i=H.Length;i>1;i--) { rc=H.elem[1]; H.elem[1]=H.elem[i]; H.elem[i]=rc; HeapAdjust(H, 1, i-1); } }/*你的程式碼將被嵌在這裡 */
輸入樣例:
第一行整數表示參與排序的關鍵字個數。第二行是關鍵字值 例如:
10
5 2 4 1 8 9 10 12 3 6
輸出樣例:
輸出由小到大的有序序列,每一個關鍵字之間由空格隔開,最後一個關鍵字後有一個空格。
1 2 3 4 5 6 8 9 10 12
6-6 歸併排序
本題要求實現二路歸併排序中的歸併操作,待排序列的長度1<=n<=1000。
函式介面定義:
void Merge(SqList L,int low,int m,int high);
其中L是待排序表,使排序後的資料從小到大排列。
###型別定義:
#include<stdio.h>#include<stdlib.h>typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;void CreatSqList(SqList *L);/*待排序列建立,由裁判實現,細節不表*/ void MergeSort(SqList L,int low,int high);void Merge(SqList L,int low,int m,int high); int main(){ SqList L; int i; CreatSqList(&L); MergeSort(L,1,L.Length); for(i=1;i<=L.Length;i++) { printf("%d ",L.elem[i]); } return 0;}void MergeSort(SqList L,int low,int high) { /*用分治法進行二路歸併排序*/ int mid; if(low<high) /*區間長度大於1*/ { mid=(low+high)/2; /*分解*/ MergeSort(L,low,mid); /*遞迴地對low到mid序列排序 */ MergeSort(L,mid+1,high); /*遞迴地對mid+1到high序列排序 */ Merge(L,low,mid,high); /*歸併*/ } }/*你的程式碼將被嵌在這裡 */
輸入樣例:
第一行整數表示參與排序的關鍵字個數。第二行是關鍵字值 例如:
10
5 2 4 1 8 9 10 12 3 6
輸出樣例:
輸出由小到大的有序序列,每一個關鍵字之間由空格隔開,最後一個關鍵字後有一個空格。
1 2 3 4 5 6 8 9 10 12
6-7 直接插入排序
本題要求實現直接插入排序函式,待排序列的長度1<=n<=1000。
函式介面定義:
void InsertSort(SqList L);
其中L是待排序表,使排序後的資料從小到大排列。
###型別定義:
typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;
裁判測試程式樣例:
#include<stdio.h>#include<stdlib.h>typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;void CreatSqList(SqList *L);/*待排序列建立,由裁判實現,細節不表*/ void InsertSort(SqList L);int main(){ SqList L; int i; CreatSqList(&L); InsertSort(L); for(i=1;i<=L.Length;i++) { printf("%d ",L.elem[i]); } return 0;}/*你的程式碼將被嵌在這裡 */
輸入樣例:
第一行整數表示參與排序的關鍵字個數。第二行是關鍵字值 例如:
10
5 2 4 1 8 9 10 12 3 6
輸出樣例:
輸出由小到大的有序序列,每一個關鍵字之間由空格隔開,最後一個關鍵字後有一個空格。
1 2 3 4 5 6 8 9 10 12
6-8 希爾排序的實現
本題要求實現一趟希爾排序函式,待排序列的長度1<=n<=1000。
函式介面定義:
void ShellInsert(SqList L,int dk);
其中L是待排序表,使排序後的資料從小到大排列。
###型別定義:
typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;
裁判測試程式樣例:
#include<stdio.h>#include<stdlib.h>typedef int KeyType;typedef struct { KeyType *elem; /*elem[0]一般作哨兵或緩衝區*/ int Length; }SqList;void CreatSqList(SqList *L);/*待排序列建立,由裁判實現,細節不表*/ void ShellInsert(SqList L,int dk);void ShellSort(SqList L);int main(){ SqList L; int i; CreatSqList(&L); ShellSort(L); for(i=1;i<=L.Length;i++) { printf("%d ",L.elem[i]); } return 0;}void ShellSort(SqList L){ /*按增量序列dlta[0…t-1]對順序表L作Shell排序,假設規定增量序列為5,3,1*/ int k; int dlta[3]={5,3,1}; int t=3; for(k=0;k<t;++k) ShellInsert(L,dlta[k]);} /*你的程式碼將被嵌在這裡 */
輸入樣例:
第一行整數表示參與排序的關鍵字個數。第二行是關鍵字值 例如:
10
5 2 4 1 8 9 10 12 3 6
輸出樣例:
輸出由小到大的有序序列,每一個關鍵字之間由空格隔開,最後一個關鍵字後有一個空格。
1 2 3 4 5 6 8 9 10 12
三、 設計文件
四、 源程式
1.
int Partition ( SqList L,int low, int high ){
int temp=L.elem[low];
while(low<high)
{
while(low<high&&L.elem[high]>=temp){
high--;
}
if(low<high){
L.elem[low]=L.elem[high];
low++;
}
while(low<high&&L.elem[low]<temp){
low++;
}
if(low<high){
L.elem[high]=L.elem[low];
high--;
}
}L.elem[low]=temp;
return low;
}
2.
void HeapAdjust( HeapType H, int s, int m){
KeyType a;
int i;
a=H.elem[s];
for(i=2*s;i<=m;i*=2){
if(i<m&&H.elem[i]<H.elem[i+1]) ++i;
if(a>=H.elem[i]) break;
H.elem[s]=H.elem[i]; s=i;
}
H.elem[s]=a;
}
3.
void Merge(SqList L,int low,int m,int high){
int i,j,now;
i=low;
j=m+1;
now=1;
int a[10000];//開個陣列儲存中間比較過程
while (i<=m&&j<=high){
if(L.elem[i]<=L.elem[j]){
a[now++]=L.elem[i++];
}
else{
a[now++]=L.elem[j++];
}
}
while (i<=m) a[now++]=L.elem[i++];
while (j<=high) a[now++]=L.elem[j++];
for (i=low,now=1;i<=high;i++){
L.elem[i]=a[now++];
}
}
4.
void InsertSort(SqList L){
int i,j;
for(i=1;i<=L.Length;i++){
L.elem[0]=L.elem[i];
for(j=i;L.elem[j-1]>L.elem[0]&&j>0;j--)
L.elem[j]=L.elem[j-1];
L.elem[j]=L.elem[0];
}
}
5.
void ShellInsert(SqList L,int dk){
for(int i=dk+1;i<=L.Length;i++){//elem[0]是哨兵
if(L.elem[i-dk]>L.elem[i]){
L.elem[0]=L.elem[i-dk];
L.elem[i-dk]=L.elem[i];
L.elem[i]=L.elem[0];
i=dk+1;
}
}
}