排序算法(七):归并排序

排序思路:
分治:将长度为len的数组array分为[0, len/2],[len/2+1, len-1],直到无法继续划分为止。
合并:将子数组逐级合并,合并过程中进行排序——申请与len相当大小的空间tmp[],比较当前要合并的2个数组的元素,从小到大,排入到tmp。排序好的tmp复写array对应的索引位置。

举例:

{22,35,16,9,5,20} 

1)分治

{22,35,16} {9,5,20} 
{22,35} {16} {9,5} {20}

2)排序

{22,35} {16} {5,9} {20}

3)合并

{16,22,35}  {5,9,20}

4)合并

{5,9,16,20,22,35}  

总结:分治后的数组从最底层开始排序,每排好一层,上移一层继续排序。降低了上层排序的比较次数,归并排序是稳定的排序算法。

 {22,35,16,9,5,20}    |
 {22,35,16} {9,5,20}   | -->>逐层拆分过程
{22,35} {16} {9,5} {20}  | 

{22,35} {16} {5,9} {20}  |
{16,22,35}  {5,9,20}   | -->>逐层排序过程
 {5,9,16,20,22,35}    |

c实现

/*
 * 合并子数组并进行排序
 */
void merge(int array[], int tmp[], int start, int mid, int end) {
    int i = start;
    int j = mid + 1;
    int k = start;
    while (i <= mid && j <= end) {
        if (array[i] > array[j])
            tmp[k++] = array[j++];
        if (array[i] < array[j])
            tmp[k++] = array[i++];
    }
    while(i<mid+1)
        tmp[k++]=array[i++];
    while(j<end+1)
        tmp[k++]=array[j++];

    //元素在tmp排好后,复写其在array中对应的位置
    for(k=start; k<=end; k++)
        array[k]=tmp[k];
}

/*
 * 拆分数组到最细,然后逐级合并
 */
void mergeSort(int array[], int tmp[], int start, int end){
    if(start>=end)
        return;
    int mid = (start + end) / 2;
    mergeSort(array, tmp, start, mid);
    mergeSort(array, tmp, mid+1, end);
    merge(array, tmp, start, mid, end);
}

时间复杂度为O(nlogn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值