内排序6:堆积排序

堆积排序可以认为是对直接选择排序法的一种改进。

堆积的定义:具有n个数据元素的序列,当且仅当满足条件 a. ki>=k2i 且 ki>=k2i+1 或者 b.ki<=k2i 且 ki<=k2i+1 时,称序列K为一个堆积,简称。有时称满足条件a的堆积为大顶堆积,满足条件b的堆积为小顶堆积

这里采用大顶堆积。
核心思想:第i趟排序就是将序列的前n-i+1个元素组成的序列转换为一个堆积,然后将堆积的第1个元素与堆积的最后那个元素交换位置。
根据这个思想,堆积排序的过程可以归纳为以下步骤:
1.建立初始堆积
2.交换堆积的第1个元素(即最大元素)与堆积的最后那个元素的位置
3.将移走最大值元素之后的剩余元素组成的序列再转换为一个堆积
4.重复上述过程的第2步和第3步n-1次。
算法中的变量i指出根结点的序号(或者指出某棵子树根结点的序号),变量j指出其左右子树根结点值最大者的序号。

算法如下:

function ADJUST(arr, i, n) {
    let j = 2 * i, //j为i结点的左孩子的序号
        temp = arr[i]
    while (j < n) {
        if (j < n - 1 && arr[j] < arr[j + 1]) {
            j++ //j给出i结点的左右孩子中值最大者的序号
        }
        if (temp >= arr[j]) {
            break
        }
        let k = Math.floor(j / 2)
        arr[k] = arr[j] //把某孩子结点上移到父结点位置
        j = 2 * j
    }
    let k1 = Math.floor(j / 2)
    arr[k1] = temp
}
function HEAPSORT(arr) {
    let n = arr.length
    let i, temp
    let k = Math.floor(n / 2)
    for (let i = k; i >= 0; i--) {
        ADJUST(arr, i, n)
    }
    for (let i = n - 1; i >= 0; i--) {
        temp = arr[i]
        arr[i] = arr[0]
        arr[0] = temp
        ADJUST(arr, 0, i)
    }
    return arr
}
var arr = [5, 3, 8, 1, 9, 2, 7, 4, 6, 10]
HEAPSORT(arr)

性能:
时间复杂度:O(nlog2n)
空间复杂度:O(1)。
是 不稳定排序方法。
不适于 链表上实现。

你可能感兴趣的:(内排序6:堆积排序)