排序算法-(7)堆排序

堆排序

堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子

该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:

大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]  

小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]  

详细步骤和原理可以看这篇:https://www.cnblogs.com/chengxiao/p/6129630.html

排序是一种选择排序,整体主要由构建初始堆+交换堆顶元素和末尾元素并重建堆两部分组成。其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)...1]逐步递减,近似为nlogn。所以堆排序时间复杂度一般认为就是O(nlogn)级。
堆排序属于选择排序算法,是不稳定

 

代码实现

//重新调整为大顶堆
function _heapify(arr, size, index) {
    let largest = index;
    const left = 2 * index + 1;
    const right = 2 * index + 2;
    if (left < size && arr[left] > arr[largest]) {
        largest = left;
    }
    if (right < size && arr[right] > arr[largest]) {
        largest = right;
    }
    if (largest !== index) {
        [arr[index], arr[largest]] = [arr[largest], arr[index]];
        _heapify(arr, size, largest);
    }
}

//这里的堆排序用的是最大堆
function heapSort(arr) {
    const result = arr.slice(0);
    const size = arr.length;
    for (let i = Math.floor(size / 2 - 1); i >= 0; i--) {
        _heapify(result, size, i);
    }
    for (let i = size - 1; i >= 0; i--) {
        [result[0], result[i]] = [result[i], result[0]];
        _heapify(result, i, 0);
    }
    return result;
}

 

posted @ 2018-08-20 15:23  汕大小吴  阅读(363)  评论(0编辑  收藏  举报