归并排序 MergeSort

1、问题  

使用归并排序对 n 个不同的数构成的数组 A [ 1.. n ] 进行排序,其中 n=2^k。

2、解析

归并排序是通过二分和分治的思想,通过不断地递归二分数组,直到每个子数组都只有一个元素,此时因为每个数组都只有一个元素所以均是有序的。

之后再通过有序表的归并,重组每个独立的数组,直到最后得到一个有序的完整数组。

3、设计

 1 void merge(int L, int R) {//有序数组的归并
 2     len  <- (L + R >> 1) - L+1;
 3     posl <- L;//L数组的起始位置
 4     posr <- L + len;//R数组的起始位置
 5     posb <- L;
 6     while posl < L + len and posr <= R
 7         //从开始位置比较,如果L数组的元素大于R数组,则将L数组的元素存进去一个,然后位置+1,否则相反
 8         if A[posl] <= A[posr]
 9             B[posb++] = A[posl++]
10         else
11             B[posb++] = A[posr++]
12     }
13     while posl < L + len//如果L数组没有放完就直接放在最后面
14         B[posb++] = A[posl++]
15     while posr <= R //如果R数组没有放完就直接放在最后面
16         B[posb++] = A[posr++]
17 }
18 void mergesort(int L, int R) {//归并排序 
19     if R == L 
20        return;//递归到每组只有一个元素返回,因为此时必定有序
21     int mid <- L + R >> 1//找到每个分块的中间值
22     mergesort(L, mid);//左边递归进行分离和合并
23     mergesort(mid+1, R);//右边递归进行分离和合并
24     merge(L, R);//左右合并
25     for  i <- L to R
26         A[i] = B[i]//排好序的结果传给A数组
27 }

4、分析

归并排序需要多次分治和进行有序表的合并操作,所以归并排序总时间=子序列排好序时间+合并时间 

一个数组长度为n,二分子区间最多有log2(n)层,所以时间复杂度为n*O(1)+n*log2(n),约等于nlog2(n)

5、源码

https://github.com/ChenyuWu0705/Algorithm-Analyze-and-Design/blob/main/Merge%20Sort.cpp

 

 

posted @ 2021-04-04 09:14  programmer_w  阅读(57)  评论(0编辑  收藏  举报