归并排序

来源:互联网 发布:地下室地坪漆的算法 编辑:程序博客网 时间:2024/06/07 09:14

归并排序算法完全按照分治模式:

分解:分解待排序的n个元素序列成n/2个子序列。

解决:使用归并排序递归的排序两个子序列。

合并:合并两个已经排序的子序列以产生已排序的答案。


摘自《算法导论》P17的伪代码:

MERGE(A,p,q,r)n1 = q - p + 1n2 = r - qlet L[1...n1 + 1] and R[1...n2 + 1] be new array//创建两个子数组的空间for i = 1 to n1L[i] = A[p + i - 1]for j = 1 to n2R[j] = A[p + j]L[n1 + 1] = InfR[n2 + 1] = Infi = 1j = 1for k =p to rif L[i] <= R[j]A[k] = L[i]i = i + 1elseA[k] = R[j]j = j + 1MERGE-SORT(A,p,r)if p < rq = [(p+q)/2]//[]是取整MERGE-SORT(A,p,q)MERGE-SORT(A,q+1,r)MERGE(A,p,q,r)

c/c++:

#include <iostream>using namespace std;void merge (int source[], int temple[], int start, int mid, int end);void merge_sort (int source[], int temple[], int start, int end);int main(){    int a[10] = {9,2,5,1,7,3,0,6,8,4};    int i, b[10];    merge_sort(a, b, 0, 9);    for(i=0; i < 10; i++)        printf("%d ", a[i]);    printf("\n");    return 0;}void merge_sort (int source[], int temple[], int start, int end){int mid = (start + end) / 2;if (end > start){merge_sort(source,temple,start,mid);merge_sort(source,temple,mid+1,end);merge(source,temple,start,mid,end);}}// 递归调用void merge (int source[], int temple[], int start, int mid, int end){int i, j, k;i = start;j = mid+1;k = start;while (i <= mid && j <= end){if (source[i] < source[j])temple[k++] = source[i++];elsetemple[k++] = source[j++];}// 合并数组while (i <= mid)temple[k++] = source[i++];while (j <= end)temple[k++] = source[j++];// 将剩余部分合并for (int i = start; i <= end; i++)source[i] = temple[i];// 覆盖原数组}
python:

# -*- coding:utf-8 -*-def merge_sort(source):    if len(source) > 1:        mid = int(len(source) / 2)        left = merge_sort(source[:mid])        right = merge_sort(source[mid:])        return merge(left, right)    #   切分之后数组大于一,接着切分    return source    #   切分完成,返回def merge(left, right):    result = []    r, l = 0, 0    while r < len(right) and l < len(left):        if right[r] < left[l]:            result.append(right[r])            r += 1        else:            result.append(left[l])            l += 1    #   两个数组每个元素比较大小,然后将较小的元素放到result,循环结束条件是较短的那个数组,全部放到result    result += right[r:]    result += left[l:]    #   将较长的那个数组剩余的部分放到result    return result    #   返回resultprint merge_sort([3, 8, 9, 10, 6, 1])

通过伪代码和实际编程语言的比较:其实可以发现两种语言实现整个算法还是有一点区别的,比如说python可以是完全按照伪代码编写的内容,分步递归,从小数组合并变成大数组,而c++实际只有两个数组,temple只是一步步合并,然后最后变成source,其实也是用temple覆盖source。