資料結構與演算法 C 歸併(Merge)排序(非遞迴)
阿新 • • 發佈:2019-02-03
7-18 排序(25 分)
給定N個(長整型範圍內的)整數,要求輸出從小到大排序後的結果。
本題旨在測試各種不同的排序演算法在各種資料情況下的表現。各組測試資料特點如下:
資料1:只有1個元素;
資料2:11個不相同的整數,測試基本正確性;
資料3:103個隨機整數;
資料4:104個隨機整數;
資料5:105個隨機整數;
資料6:105個順序整數;
資料7:105個逆序整數;
資料8:105個基本有序的整數;
資料9:105個隨機正整數,每個數字不超過1000。
輸入格式:
輸入第一行給出正整數N(≤105),隨後一行給出N個(長整型範圍內的)整數,其間以空格分隔。
輸出格式:
在一行中輸出從小到大排序後的結果,數字間以1個空格分隔,行末不得有多餘空格。
輸入樣例:
11
4 981 10 -17 0 -20 29 50 8 43 -5
輸出樣例:
-20 -17 -5 0 4 8 10 29 43 50 981
非遞迴進行實現 思路很類似連結串列吧。方法也是倆個倆個的合併。
程式碼:
#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <ctype.h> #define MAX 1000000 /** merge 排序 非遞迴實現**/ void swap(int x,int y) /**交換函式**/ { int z; z=y; y=x; x=z; } long long compare(long long x,long long y) /**比較函式**/ { if(x>=y)return 1; else return 0; } void conbine(long long *arr,int* idex,int x,int y) /**兩個陣列的合併(歸併排序內用來合併的函式)**/ { int p1=x,p2=y,head,next; /** x,y 分別是陣列的第一個下標 實現 類似於連結串列 , head 是 頭 next 是 正在插入時指標 idex 是 記錄 每個數的 指向下一個比他大的數的下標 **/ if(compare(arr[x],arr[y])) /**先找到 倆數組合並後的 第一個下標**/ { head=next=y; p2=idex[p2]; } else { head=next=x; p1=idex[p1]; } while(p1>=0&&p2>=0) /** 倆陣列比較 小的出去**/ { if(compare(arr[p1],arr[p2])) { idex[next]=p2; p2=idex[p2]; } else { idex[next] =p1; p1=idex[p1]; } next=idex[next]; } while(p1>=0) /**再把剩的全踢出去**/ { idex[next]=p1; p1=idex[p1]; next=idex[next]; } while(p2>=0) { idex[next]=p2; p2=idex[p2]; next=idex[next]; } idex[next]=-head; /**合併後陣列最後一個等於頭下標的負值**/ } void merge(long long *arr,int *idex,int n) /**歸併排序**/ { int i=1,j,x,y,f; f=1; while(1) { while(i<=n&&idex[i]>0) i++; /**迴圈 每次找倆個 陣列來合併**/ if(i<=n) x=i++; else x=0; while(i<=n&&idex[i]>0) i++; if(i<=n) y=i++; else y=0; //printf("%d %d\n",x,y); if(x&&y) /**找到倆個 合併**/ { conbine(arr,idex,-idex[x],-idex[y]); f=0; } /*for(j=1;j<=n;j++) printf("%d ",idex[j]); printf("\n");*/ if(f) break; /**f 意義是如果 最後 只找到一個 負數(頭下標的負值) 就排好序了**/ if(i>n) /** 小排序 一次後 進行第二次小排序**/ { i=1; f=1; } } } void display(long long *arr,int *idex,int x) /**用來輸出 不多說了**/ { //printf("->"); int f=1; while(x>=0) { if(f) f=0; else printf(" "); printf("%lld",arr[x]); x=idex[x]; } } int main(){ int n,i,j; scanf("%d",&n); long long *arr; arr = (long long *)malloc((n+2)*sizeof(long long)); /** 陣列最好從 下標 1 開始 ,為了最後解決頭下標負數 0 = -0的矛盾**/ for(i=1;i<=n;i++) { scanf("%lld",&arr[i]); } int *idex; idex=(int*)malloc((n+2)*sizeof(int)); for(i=1;i<=n;i++) idex[i]=-i; merge(arr,idex,n); //conbine(arr,idex,1,2); for(i=1;i<=n;i++) { if(idex[i]<0) { display(arr,idex,-idex[i]); break; } } return 0; }