排序算法——归并排序

介绍

从头实现归并排序。
归并排序(MergeSort),是采用分治思想的一种算法,通过把要排序的数组依次递归对半拆分,当子数组达到长度1时,即只有一个元素,认为其为有序的,结束递归。使用递归排序时,无论原数组序列的排序情况如何,都要递归到最底层,所以时间复杂度相对固定。为 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)). 归并排序可分为二路归并和多路归并,最常用的是二路归并,下文示例亦是针对二路归并排序的。另外,归并排序是稳定的。


图解

拆分阶段:

image-20210509204359870

合并阶段:

image-20210509204925849


示例代码

def mergeSort(arr):  # 拆分
    if len(arr) // 2 == 0:
        return arr
    return merge(mergeSort(arr[0:len(arr) // 2]), mergeSort(arr[len(arr) // 2:]))


def merge(a_l, a_r):  # 合并
    a = [0] * (len(a_l) + len(a_r))
    p_l, p_r = 0, 0  # 左右数组的左右指针
    while p_l < len(a_l) and p_r < len(a_r):
        if a_l[p_l] > a_r[p_r]:
            a[p_l + p_r] = a_r[p_r]
            p_r += 1
        else:
            a[p_l + p_r] = a_l[p_l]
            p_l += 1
    while p_l < len(a_l):  # 若左数组剩余,依次填入
        a[p_l + p_r] = a_l[p_l]
        p_l += 1
    while p_r < len(a_r):  # 若右数组剩余,依次填入
        a[p_l + p_r] = a_r[p_r]
        p_r += 1
    return a


if __name__ == '__main__':
    a = [16, 55, 64, 35, 24, 4, 85, 68, 84, 41]
    out = mergeSort(a)
    print(out)
    
[out]:
[4, 16, 24, 35, 41, 55, 64, 68, 84, 85]
import java.util.Arrays;

public class MergeSort {
    public static void main(String[] args) {
        int[] arr = new int[]{97, 76, 84, 35, 60, 53, 59, 62, 93, 53, 37, 19, 9};
        arr = mergeSort(arr);
        for (int i : arr) {
            System.out.println(i);
        }

    }

    public static int[] mergeSort(int[] arr) {
        int len = arr.length;
        if (len / 2 == 0) {
            return arr;
        }
        int[] arr_l = mergeSort(Arrays.copyOfRange(arr, 0, len / 2));
        int[] arr_r = mergeSort(Arrays.copyOfRange(arr, len / 2, len));
        return merge(arr_l, arr_r);
    }

    public static int[] merge(int[] arr_l, int[] arr_r) {
        int len_l = arr_l.length;
        int len_r = arr_r.length;
        int[] arr = new int[len_l + len_r];
        int p_l = 0;
        int p_r = 0;
        while (p_l < len_l && p_r < len_r) {
            if (arr_l[p_l] < arr_r[p_r]) {
                arr[p_l + p_r] = arr_l[p_l];
                p_l++;
            } else {
                arr[p_l + p_r] = arr_r[p_r];
                p_r++;
            }
        }
        while (p_l < len_l) {
            arr[p_l + p_r] = arr_l[p_l];
            p_l++;
        }
        while (p_r < len_r) {
            arr[p_r + p_l] = arr_r[p_r];
            p_r++;
        }
        return arr;

    }
}
[out]:
9
19
35
37
53
53
59
60
62
76
84
93
97

];
p_r++;
}
return arr;

}

}
[out]:
9
19
35
37
53
53
59
60
62
76
84
93
97








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值