引言
只要設計到數據,就會涉及到數據的排序問題,比如給你隨機給你五個整數 3,1,5,2,4 。讓你從小到大進行排序,那我們該怎樣纔是實現對這些整數的排序呢 ?
答案是多種多樣的,比如用插入排序、希爾排序、堆排序、歸併排序、快速排序等等,這些排序方法都可以實現對整數排序,而這篇文章要講的就是歸併排序
本文將從以下幾個問題對歸併排序進行分析和講解:
- 什麼是歸併排序?
- 歸併排序的大概過程是什麼?
- 怎樣用代碼實現歸併排序?
- 歸併排序的代碼詳解。
什麼是歸併排序?
下面看百度百科對歸併排序的定義:
歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。歸併排序是一種穩定的排序方法。
簡單理解:歸併排序一個分兩大部,第一步分,第二步合。
下面先看一個動圖:
歸併排序的大概過程是什麼?
我們用歸併排序講一個例子來說明,要排序的數組爲3,1,5,2,4.
歸併排序第一步:分
分採取一份爲二的方法(所以這個歸併排序又叫二路歸併排序)
mid=(first+last)/2(first是最左邊,last是最右邊),採取前面的公式,分爲【first,mid】和【mid+1,last】
如上圖所示,直到分成一個一個的數,分的話可以採取遞歸調用的方法。
再看第二大步:合
合是指把兩個數組合成一個數組,而且合成之後數組是有序的。
合成方法:在合成過程中需要一個臨時數組來存合成的結果。可以定義兩個變量 i 和 j 分別指向兩個數組的第一個元素,比較他倆誰小。就是那個對應的元素放到臨時數組裏面,指向數組的變量後移。只要其中一個變量走到頭位置。
如果是其中一個走到頭了,但是另一個還未到頭,這時候就需要把數組剩餘的元素放到臨時數組裏面。
上面說的是把兩個數組合二爲一,但是兩個數組其實是一個數組中兩塊不同的部分(用下標區分的),等上面合成結束,就把臨時數組放到原數組裏面,下面看合代碼。
//將兩個有序數列a[first...mid]和a[mid...last]合併 void MergeArray(int a[],int first,int mid,int last,int temp[]) { int i=first, j=mid+1; int m=mid , n=last; int k=0; while(i<=m&&j<=n) { if(a[i]<=a[j]) temp[k++]=a[i++]; else temp[k++]=a[j++]; } while(i<=m) temp[k++]=a[i++]; while(j<=n) temp[k++]=a[j++]; for(i=0;i<k;i++) a[first+i]=temp[i]; }
怎樣用代碼實現歸併排序?
下面看完成的代碼
#include<iostream> using namespace std; //將兩個有序數列a[first...mid]和a[mid...last]合併 void MergeArray(int a[],int first,int mid,int last,int temp[]) { int i=first, j=mid+1; int m=mid , n=last; int k=0; while(i<=m&&j<=n) { if(a[i]<=a[j]) temp[k++]=a[i++]; else temp[k++]=a[j++]; } while(i<=m) temp[k++]=a[i++]; while(j<=n) temp[k++]=a[j++]; for(i=0;i<k;i++) a[first+i]=temp[i]; } //歸併排序函數 穩定 void MergeSort(int a[],int first,int last,int temp[]) { if(first<last) { int mid=(first+last)/2; MergeSort(a,first,mid,temp); MergeSort(a,mid+1,last,temp); MergeArray(a,first,mid,last,temp); } } //輸出數組的值 void printf(int arr[],int len) { for(int i=0;i<len;i++) cout<<arr[i]<<" "; cout<<endl; } int main() { //要排序的數組 int arr[]={3, 44,38, 5,47,15,36,26,27,2 ,46,4 ,19,50,48}; int len=15;//要排序的數組長度 int temp[1]; //排序 MergeSort(arr,0,len-1,temp); //輸出 printf(arr,len); return 0; }
運行結果:
歸併排序代碼詳解
- 第一步分,首先要知道怎樣分,採取的是遞歸調用,記得注意遞歸的結束條件
- 第二步合,把兩個小數組合成一個大數組,合的過程應該是啥,一定要清楚
本文參考以及引用: