摘要:二叉堆数据结构是一种特殊的二叉树,他能高效快速的找出最大值和最小值,常应用于优先队列和著名的堆排序算法中。
二叉堆数据结构是一种特殊的二叉树,他能高效、快速的找出最大值和最小值,常应用于优先队列和著名的堆排序算法中。
二叉堆二叉堆有以下两个特性:
是一颗完全二叉树,表示数的每一层都有左侧和右侧子节点(除最后一层的叶节点),并且最后一层的叶节点尽可能是左侧子节点
二叉堆不是最小堆就是最大堆,所有节点都大于等于(最大堆)或者小于等于(最小堆)每个他的子节点。
创建最小堆类class MinHeap { constructor(compareFn = defaultCompare) { this.compareFn = compareFn; this.heap = []; } }二叉堆的数组表示
static getLeftIndex(index) { return (2 * index) + 1; } static getRightIndex(index) { return (2 * index) + 2; } static getParentIndex(index) { if (index === 0) { return undefined; } return Math.floor((index - 1) / 2); } size() { return this.heap.length; } isEmpty() { return this.size() <= 0; } clear() { this.heap = []; }查找二叉堆最小值或者最大值
findMinimum() { return this.isEmpty() ? undefined : this.heap[0]; }交换函数实现
function swap(array, a, b) { /* const temp = array[a]; array[a] = array[b]; array[b] = temp; */ [array[a], array[b]] = [array[b], array[a]]; }向堆中插入新值
insert(value) { if (value != null) { const index = this.heap.length; this.heap.push(value); this.siftUp(index); return true; } return false; }; //上移操作 siftUp(index) { let parent = this.getParentIndex(index); while ( index > 0 && this.compareFn(this.heap[parent], this.heap[index]) === Compare.BIGGER_THAN ) { swap(this.heap, parent, index); index = parent; parent = this.getParentIndex(index); } }二叉堆中导出最大值或最小值
extract() { if (this.isEmpty()) { return undefined; } if (this.size() === 1) { return this.heap.shift(); } const removedValue = this.heap[0]; this.heap[0] = this.heap.pop(); this.siftDown(0); return removedValue; }; //下移操作 siftDown(index) { let element = index; const left = MinHeap.getLeftIndex(index); const right = this.getRightIndex(index); const size = this.size(); if ( left < size && this.compareFn(this.heap[element], this.heap[left]) === Compare.BIGGER_THAN ) { element = left; } if ( right < size && this.compareFn(this.heap[element], this.heap[right]) === Compare.BIGGER_THAN ) { element = right; } if (index !== element) { swap(this.heap, index, element); this.siftDown(element); } }创建最大堆类
class MaxHeap extends MinHeap { constructor(compareFn = defaultCompare) { super(compareFn); this.compareFn = compareFn; this.compareFn = reverseCompare(compareFn); } }
其他操作跟最小堆类一样,这里就不多加赘述。
堆排序算法heapify(array) { if (array) { this.heap = array; } const maxIndex = Math.floor(this.size() / 2) - 1; for (let i = 0; i <= maxIndex; i++) { this.siftDown(i); } return this.heap; }; getAsArray() { return this.heap; }; //构建最大堆函数 function buildMaxHeap(array, compareFn) { for (let i = Math.floor(array.length / 2);i >= 0; i -= 1){ heapify(array, i, array.length, compareFn); return array; } } //堆排序算法实现 function heapSort(array, compareFn = defaultCompare) { let heapSize = array.length; //用数组创建一个最大堆用作源数据 buildMaxHeap(array, compareFn); while(heapSize > 1){ //创建最大堆后,最大的值会被存储在堆的第一个位置,我们将它替换为堆的最后一个值,将堆的大小-1 swap(array, 0, --heapSize); //将堆的根节点下移并重复步骤2直到堆的大小为1 heapify(array, 0, heapSize, compareFn); } return array; }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/106917.html
摘要:模型优先队列是允许至少下列两种操作的数据结构以及找出返回并删除优先队列中最小的元素。左式堆也是二叉树,左式堆和二叉堆的唯一区别是左式堆不是理想平衡,而实际上趋向于非常不平衡。事实上,沿左式堆的右路径是该堆中的最短路径。 6.1 模型 优先队列是允许至少下列两种操作的数据结构:insert 以及 deleteMin(找出、返回并删除优先队列中最小的元素)。 insert 操作等价于 en...
摘要:二叉堆的有趣之处在于,其逻辑结构上像二叉树,却是用非嵌套的列表来实现。二叉堆结构性质为了更好地实现堆,我们采用二叉树。图完全二叉树有意思的是我们用单个列表就能实现完全树。下列所示的代码是完全二叉堆的实现。 优先队列的二叉堆实现 在前面的章节里我们学习了先进先出(FIFO)的数据结构:队列(Queue)。队列有一种变体叫做优先队列(Priority Queue)。优先队列的出队(Dequ...
摘要:一个常见的例子就是优先队列,还有排序算法之一的堆排序。另外我们还将学习堆排序,并将使用实现堆。堆排序在堆排序中,我们需要用给定的值构建一个一个堆。伪代码如下从上面的伪代码可以看到,堆排序的第一步就是构建一个堆。 堆是什么? 堆是基于树抽象数据类型的一种特殊的数据结构,用于许多算法和数据结构中。一个常见的例子就是优先队列,还有排序算法之一的堆排序。这篇文章我们将讨论堆的属性、不同类型的堆...
阅读 766·2019-08-29 16:32
阅读 838·2019-08-29 12:31
阅读 3211·2019-08-26 18:26
阅读 3156·2019-08-26 12:20
阅读 1730·2019-08-26 12:00
阅读 3009·2019-08-26 10:58
阅读 2812·2019-08-23 17:08
阅读 2310·2019-08-23 16:32