算法基础之归并排序

归并排序思想遵循分治法

在实现上有三个操作:
分解,将待排序的n个元素的序列分解成两个n/2元素的子序列;
解决,使用归并排序递归排序子序列;
合并,合并两个已排序的子序列。
归并排序算法的关键操作是合并步骤中两个已排序序列的合并。

伪代码表示

其中A是数组,p、q、r是数组下标,满足p<=q

//合并
MERGE(A, p, q, r)
n1 = q - p + 1
n2 = r - q
let L[1..n1 + 1] and R[1..n2 + 1] be new arrays
for i = 1 to n1
    L[i] = A[p + i - 1]
for j = 1 to n2
    R[j] = A[q + j]
L[n1 + 1] = ∞
R[n2 + 1] = ∞
i = 1
j = 1
for k = p to r
    if L[i] <= R[j]
        A[k] = L[i]
        i = i + 1
    else 
        A[k] = R[j]
        j = j + 1

//排序算法(q向下取整)
MERGE-SORT(A, p, r)
if p < r
    q = (p + r) / 2
    MERGE-SORT(A, p, q)
    MERGE-SORT(A, q + 1, r)
    MERGE(A, p, q, r)

Java代码表示

public static void merge(int[] queue, int p, int q, int r) {
        int i = p, j = q, m = q + 1, n = r, k = 0;
        int temp[] = new int[r - p + 1];
        while (i <= j && m <= n) {
            if (queue[i] < queue[m]) {
                temp[k++] = queue[i++];
            } else {
                temp[k++] = queue[m++];
            }
        }
        while (i <= j) {
            temp[k++] = queue[i++];
        }
        while (m <= n) {
            temp[k++] = queue[m++];
        }
        System.arraycopy(temp, 0, queue, p, temp.length);
    }

    public static void mergeSort(int[] queue, int p, int r) {
        if (p > r) {
            int q = (p + r) / 2;
            mergeSort(queue, p, q);
            mergeSort(queue, q + 1, r);
            // 合并两个有序序列
            merge(queue, p, q, r);
        }
    }

排序过程大致为:

百度来的图片

归并排序的时空复杂度

1、设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)
2、因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。
3、归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间:n + logn;所以空间复杂度为: O(n)


以上,就是笔者对于归并排序的初略见解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值