堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

具体算法描述如下:

1、将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
2、将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),
且满足R[1,2…n-1]<=R[n];
3、由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

时间复杂度:
最好:O(nlog2n),
最坏:O(nlog2n),
平均:O(nlog2n)。

/*方法说明:堆排序 @param array 待排序数组*/            
const heapSort = (arr) => {
  if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') {
    //建堆
    let heapSize = array.length, temp;
    for (let i = Math.floor(heapSize / 2); i >= 0; i--) {
        heapify(array, i, heapSize);
    }

    //堆排序
    for (let j = heapSize - 1; j >= 1; j--) {
        temp = array[0];
        array[0] = array[j];
        array[j] = temp;
        heapify(array, 0, --heapSize);
    }
  } else {
    return 'array is not an Array!';
  }
}
/*方法说明:维护堆的性质 @param arr 数组 @param x 数组下标 @param len 堆大小*/
const heapify = (arr, x, len) => {
  if (Object.prototype.toString.call(arr).slice(8, -1) === 'Array' && typeof x === 'number'){
    let l = 2 * x, r = 2 * x + 1, largest = x, temp;
    if (l < len && arr[l] > arr[largest]) {
        largest = l;
    }
    if (r < len && arr[r] > arr[largest]) {
        largest = r;
    }
    if (largest != x) {
        temp = arr[x];
        arr[x] = arr[largest];
        arr[largest] = temp;
        heapify(arr, largest, len);
    }
  } else {
    return 'arr is not an Array or x is not a number!';
  }
}
    原文作者:算法
    原文地址: https://www.twblogs.net/a/5bd3c6892b717778ac20d4d6
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞