歸併排序
歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。歸併排序是一種穩定的排序方法。
該算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞歸求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。
基本思想
先遞歸分組再合併相鄰的兩個組
1.將一個待排序序列進行分組,分爲左子數組和右子數組,對左右子數組進行排序形成有序的子數組,在進行合併成一個完整的有序序列。
2.對左右子數組進行排序使用遞歸的方式進行,就是對左右子數組繼續進行分組,直到每個組中只有一個元素,說明分組完成,組中的元素已經達到有序,然後在合併相鄰的兩個組。
3.合併方式爲:首先創建一個和原數組相同的數組用來存放合併後的數組,然後比較左右子數組的第一個元素,誰小就把誰放在新數組的0索引處。(如果左子數組的第一個數比右子數組的第一個數小就把左子數組第一個數放在新數組的0索引處,在把左子數組+1繼續和右子數組的第一個數進行比較,誰小就把誰放在新數組的1索引處,如果右子數組的第一個數小,就右子數組+1繼續和左子數組+1進行比較,誰小就把誰放在新數組的2索引處,依次進行比較,直到合併成一個組,就把新數組裏的元素都賦值給原數組)
分解合併的過程圖解
歸併排序代碼(C語言)
#include <stdio.h>
#include <stdlib.h>
//歸併排序
//將兩個有序子數組合並操作
void Sort(int a[],int temp[],int left,int mid,int right)
{
int i,j,t;
i = left; //左序列指針
j = mid+1; //右序列指針
t = 0; //臨時數組指針
while (i <= mid && j <= right)
{
if (a[i] < a[j])
{
temp[t++] = a[i++];
}
else
{
temp[t++] = a[j++];
}
}
while (i<=mid) //將左邊剩餘元素填充進temp中
{
temp[t++] = a[i++];
}
while (j<=right) // 將右序列剩餘元浸塑填充進temp中
{
temp[t++] = a[j++];
}
t=0;
//將temp中的元素全部拷貝到原數組中
while (left <= right)
{
a[left++] = temp[t++];
}
}
//使用遞歸分組進行
void Merge_Sort(int a[],int temp[],int left,int right)
{
if (left<right)
{
int mid = (left+right)/2;
Merge_Sort(a,temp,left,mid); // 左邊歸併排序,使得左子序列有序
Merge_Sort(a,temp,mid+1,right); //右邊歸併排序,使得右子序列有序
Sort(a,temp,left,mid,right); //將兩個有序子數組合並操作
}
}
void main()
{
int a[]={16,36,69,56,65,45,52,36,96,2};
int n=sizeof(a)/sizeof(int); //計算數組元素
int i,b[n];
Merge_Sort(a,b,0,n);
for ( i = 0; i < n; i++)
{
printf("%d ",a[i]);
}
system("pause"); //防止控制檯閃退
}
參考文獻
圖解排序算法(四)之歸併排序