首页 > 代码库 > 排序算法分析【五】:归并排序(附Python&C++代码)

排序算法分析【五】:归并排序(附Python&C++代码)

归并排序:将两个已经排序的串行合并成一个串行的操作。

算法原理

先看动态图:


算法描述如下:

  1. 申请空间,使其大小为两个已经排序串行之和,该空间用来存放合并后的串行;
  2. 设定两个指针,最初位置分别为两个已经排序串行的起始位置;
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
  4. 重复步骤3直到某一指针到达串行尾;
  5. 将另一串行剩下的所有元素直接复制到合并串行尾。

算法实现

Python版:

#-*- encoding: utf-8 -*-        

def merge_sort(list_one, list_two):
    # 归并排序
    list_merge = []
    i = 0; j = 0 
    while i < len(list_one) and j < len(list_two):
        if list_one[i] <= list_two[j]:
            list_merge.append(list_one[i])
            i += 1 
        else:
            list_merge.append(list_two[j])
            j += 1
        print 'i = {}, j = {}'.format(i, j)
        print list_merge

    while i < len(list_one):
        list_merge.append(list_one[i])
        i += 1 
    while j < len(list_two):
        list_merge.append(list_two[j])
        j += 1 
    return list_merge
        
list_one = [1, 3, 5, 6, 8, 10, 12, 13]
list_two = [2, 4, 7, 9, 11, 14, 15, 16, 17, 18]

print merge_sort(list_one, list_two)
结果为:

>>> ================================ RESTART ================================
>>> 
i = 1, j = 0
[1]
i = 1, j = 1
[1, 2]
i = 2, j = 1
[1, 2, 3]
i = 2, j = 2
[1, 2, 3, 4]
i = 3, j = 2
[1, 2, 3, 4, 5]
i = 4, j = 2
[1, 2, 3, 4, 5, 6]
i = 4, j = 3
[1, 2, 3, 4, 5, 6, 7]
i = 5, j = 3
[1, 2, 3, 4, 5, 6, 7, 8]
i = 5, j = 4
[1, 2, 3, 4, 5, 6, 7, 8, 9]
i = 6, j = 4
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
i = 6, j = 5
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
i = 7, j = 5
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
i = 8, j = 5
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
>>> 

C++版:

#include <iostream>
using namespace std;

void print (int st_bf[], size_t size){
    for (size_t i = 0; i < size; i++)
    {
        cout<< st_bf[i] << " ";
    }
    cout<< endl;
}

void merge_sort(int *list_one, size_t len_list_one,
                int *list_two, size_t len_list_two){
    // 归并排序
    // 申请空间
    int list_merge[len_list_one+len_list_two];
    size_t i = 0, j = 0, k = 0; // k保存合并后的长度
    for ( ; (i<len_list_one) and (j<len_list_two); ++k){
        if (list_one[i] <= list_two[j]){
            list_merge[k] = list_one[i++];
        } else {
            list_merge[k] = list_two[j++];
        }
        cout << "i = " << i << ", j = " << j << ", k = " << k << endl;
        print(list_merge, k+1);
    }

    // 以下复制尾部大元素序列
    while (i < len_list_one) list_merge[k++] = list_one[i++];
    while (j < len_list_two) list_merge[k++] = list_two[j++];

    cout << "i = " << i << ", j = " << j << ", k = " << k << endl;
    print(list_merge, k);

}


int main(){
    int list_one[] = {1, 3, 5, 6, 8, 10, 12, 13};
    int list_two[] = {2, 4, 7, 9, 11, 14, 15, 16, 17, 18};
    size_t len_list_one = sizeof(list_one)/sizeof(list_one[0]);
    size_t len_list_two = sizeof(list_two)/sizeof(list_two[0]);
    merge_sort(list_one, len_list_one, list_two, len_list_two);
    return 0;
}
结果同上,不在贴出。

本文由@The_Third_Wave(Blog地址:http://blog.csdn.net/zhanh1218)原创。还有未涉及的,会不定期更新,有错误请指正。

如果你看到这篇博文时发现没有不完整,那是我为防止爬虫先发布一半的原因,请看原作者Blog。

如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址。