归并排序(Merge Sort)
归并排序(Merge-Sort)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。—百度百科
- 时间复杂度:最好 O(n)=O(nlogn);平均O(n)=O(nlogn);最差O(n)=O(nlogn)
- 空间复杂度:O(n)=O(n)
- 稳定性: 稳定
算法描述
写作功底有限,不明白的推荐看一下麻省理工学院的算法导论公开课。
归并(Merge)
归并算法是指将两个有序序列合并为一个有序序列的方法。
例如,现有两个有序序列A[1,3,5], B[2,4,6],将其合并为一个序列C。
分别对A,B建一个游标索引,初始值为0。
第一步比较A,B索引的值A[1,3,5],B[2,4,6],1 < 2,所以C=[1,…], A的索引+1。
第二步比较A,B索引的值A[1,3,5],B[2,4,6],3 > 2,所以C=[1,2,…], B的索引+1。
第三步比较A,B索引的值A[1,3,5],B[2,4,6],3 < 4,所以C=[1,2,3,…], A的索引+1。
第四步比较A,B索引的值A[1,3,5],B[2,4,6],5 > 4,所以C=[1,2,3,4…], B的索引+1。
第五步比较A,B索引的值A[1,3,5],B[2,4,6],5 < 6,所以C=[1,2,3,4,5…],A的索引+1。
此时A中元素已全部取完,后续只需将B中元素按次序放入C即得C[1,2,3,4,5,6]
归并排序(Merge Sort)
- 分解:将序列分为两组A,B,再对A,B各自分成两组。依次类推,当每组中只有一个元素时,可认为每个小组都是有序的。
- 归并:将步骤1中分成的小组,递归的进行两两归并,直到归并为一个数组。
图片来自维基百科
排序示例
示例代码
public static void MergeSort(int[] S){ //C#
MergeSort(S, 0, S.Length - 1);
}
private static void MergeSort(int[] S, int first, int last){
if (first < last){
int mid = (first + last) / 2;
MergeSort(S, first, mid); //分解
MergeSort(S, mid + 1, last);//分解
Merge(S, first, mid, last); //归并
}
}
/// <summary>
/// 归并,将两个有序序列合并为一个有序序列
/// </summary>
private static void Merge(int[] S, int first, int mid, int last){
int[] temp = new int[last - first + 1];
int i = first;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= last){
if (S[i] <= S[j]){
temp[k++] = S[i++];
} else {
temp[k++] = S[j++];
}
}
while (i <= mid){
temp[k++] = S[i++];
}
while (j <= last){
temp[k++] = S[j++];
}
Array.Copy(temp, 0, S, first, temp.Length);
}
def merge_sort(s): #Python
if len(s) <= 1:
return s
mid = len(s) // 2
left = merge_sort(s[:mid])
right = merge_sort(s[mid:])
#注意:并非原地排序,是新建了一个列表并返回
return merge(left, right)
def merge(left, right):
result = []
i = 0
j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
文中若有什么错误,欢迎留言指正。
转载请保留出处:http://blog.csdn.net/x1060549/article/details/78781643