Sort排序專題(7)歸併排序(MergeSort)(C++實現)
歸併排序(MergeSort)
歸併排序(Merge Sort):是建立在歸併操作上的一種有效,穩定的排序演算法,該演算法是採用分治法的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為二路歸併。
思想:將陣列分解直到每個分組只有一個元素,在進行兩兩歸併,得到有序序列,在將有序序列進行兩兩歸併然後直到最終的合併得到有序序列。
圖解如下:
①先將總序列一分為二,再將各個子序列一分為二,直到每個分組只有一個元素10,4,6,3,8,2,5,7。
②在對其序列進行兩兩合併,10和4比較併合並,6和3…依此類推,得到4 10,3 6,2 8,5 7。
③再對有序序列4 10和3 6進行比較合併…依此類推得到3 4 6 10,2 5 7 8兩個有序序列
④最終對兩個有序序列進行比較合併3 4 6 10,2 5 7 8,得到最終有序序列2 3 4 5 6 7 8 10.
注:先分解到每個分組只有一個元素,後進行比較合併,分解和合並都為遞迴。一直到最後合併為一個有序序列即可。
程式碼實現
#include<iostream>
#include<malloc.h>
using namespace std;
void Merge(int arr[],int l,int h) //歸併函式
{
int l1, l2, h1, h2,i = 0;
l1 = l; //最左邊指標,指下標
h1 = l + (h - l) / 2; //中間值指標,指下標
l2 = h1 + 1; //中間值+1指標,指下標
h2 = h; //最右邊指標,指下標
int *pTmp = (int *)malloc(sizeof(int)*(h - l + 1)); //申請空間
while(l1 <= h1 && l2 <= h2)
{
if(arr[l1] < arr[l2]) //比較arr[l1]和arr[l2],將較小的值放入pTmp中,並且移動指標,
{
pTmp[i] = arr[l1];
l1++;
}
else
{
pTmp[i] = arr[l2];
l2++;
}
i++;
}
while(l1 <= h1) //將未遍歷完的一邊的元素按順序依次輸入pTmp中
{
pTmp[i] = arr[l1];
l1++;
i++;
}
while(l2 <= h2)
{
pTmp[i] = arr[l2];
l2++;
i++;
}
for(i = 0; i < h - l + 1;i++) //將pTmp還給arr陣列,進行歸併。
{
arr[l + i] = pTmp[i];
}
free(pTmp); //釋放申請的空間
pTmp = NULL;
}
void MergeSort(int arr[],int l,int h)
{
if(arr == NULL || l >= h) return ;
int Mid = l + (h - l)/2; //找出中間值
MergeSort(arr,l,Mid); //分治中間值左邊 (遞迴直到2個元素)
MergeSort(arr,Mid + 1,h); //分治中間值右邊
Merge(arr,l,h); //歸併
}
int main()
{
int *arr = NULL; //指標==陣列 指標需要初始化
int n,len;
cin>>n;
arr = (int*)malloc(sizeof(int)*n); //指標使用需要malloc空間(malloc空間虛擬地址連續,實體地址不一定連續)
for(int i = 0; i < n; i++)
{
cin>>arr[i];
}
MergeSort(arr,0,n-1);
for(int i = 0; i < n; i++)
{
cout<<arr[i]<<" ";
}
free(arr);
arr = 0;
return 0;
}
時間複雜度
歸併排序比較佔用記憶體,但卻是一種效率高且穩定的演算法。
時間複雜度無論好壞都是O(nlogn)。是一種相對穩定的排序演算法,分而治之是主要思想。
相關文章
- 歸併排序MergeSort的C實現排序
- MergeSort,歸併排序的Python實現排序Python
- Sort排序專題(5)快速排序(QuickSort)(C++實現)排序UIC++
- php實現 歸併排序,快速排序PHP排序
- 排序演算法之「歸併排序(Merge Sort)」排序演算法
- go 實現歸併排序Go排序
- Java實現歸併排序Java排序
- 原地歸併排序 Merge Sort in place排序
- C++快速排序與歸併排序的實現(LeetCode 912)C++排序LeetCode
- 使用 Swift 實現歸併排序Swift排序
- [排序] 歸併排序排序
- 歸併排序演算法(merge_Sort)排序演算法
- 快速排序&&歸併排序排序
- 七、排序,選擇、冒泡、希爾、歸併、快速排序實現排序
- 利用java實現插入排序、歸併排序、快排和堆排序Java排序
- 歸併排序加例題排序
- 歸併排序排序
- ForkJoin和氣泡排序組合實現的歸併排序排序
- 利用遞迴實現連結串列的排序(歸併排序)遞迴排序
- 直播系統原始碼,實現快速排序和歸併排序原始碼排序
- 歸併排序與快速排序的一個實現與理解排序
- 四、歸併排序 && 快速排序排序
- 三種語言實現歸併排序(C++/Python/Java)排序C++PythonJava
- 歸併排序的非遞迴實現排序遞迴
- 歸併排序與快速排序的簡明實現及對比排序
- 歸併排序(java機試題)排序Java
- [C++]歸併排序(連結串列描述)C++排序
- 資料結構 歸併排序 C++資料結構排序C++
- 歸併排序--二路排序排序
- 排序演算法__歸併排序排序演算法
- 排序演算法:歸併排序排序演算法
- 歸併排序和基數排序排序
- 歸併排序--排序演算法排序演算法
- 排序演算法 - 歸併排序排序演算法
- 排序演算法——歸併排序排序演算法
- 排序演算法(歸併排序)排序演算法
- php插入排序,快速排序,歸併排序,堆排序PHP排序
- java歸併排序Java排序