- 最小堆
最小堆有两个方法:插入和移出。
插入:将元素放置在堆的末尾,递归地将它与父节点元素对比,如果其值比父节点小就交换位置,直至其值大于等于父节点或移至到堆的首部。
移出:堆中最小的值位于堆顶,先将其与堆尾元素交换位置,移出堆尾元素;将堆顶元素递归地与左右子节点元素比较,如果其值大于子节点就交换位置,直至其值小于等于子节点。let heap = []; function swap(index1, index2) { [heap[index1], heap[index2]] = [heap[index2], heap[index1]] } function shiftup(index) { let parentIndex = Math.floor((index - 1) / 2); if (index != 0 && heap[parentIndex] > heap[index]) { swap(parentIndex, index); shiftup(parentIndex); } } function shiftDown(index) { let leftNodeIndex = (index + 1) * 2 - 1, rightNodeIndex = (index + 1) * 2 if (leftNodeIndex < heap.length && heap[leftNodeIndex] < heap[index]) { swap(leftNodeIndex, index); shiftDown(leftNodeIndex); } if (rightNodeIndex < heap.length && heap[rightNodeIndex] < heap[index]) { swap(rightNodeIndex, index); shiftDown(rightNodeIndex); } } function insert(val) { heap.push(val); shiftup(heap.length - 1); } function remove() { swap(0, heap.length - 1); let temp = heap.pop(); shiftDown(0); return temp; }
- 最大堆
最大堆与最小堆的实现思路一样,只是需要父子节点交换的条件不同;最大堆的最大值位于堆顶,所以需要在父节点小于子节点时进行交换位置。
let heap = []; function swap(index1, index2) { [heap[index1], heap[index2]] = [heap[index2], heap[index1]] } function shiftup(index) { let parentIndex = Math.floor((index - 1) / 2); if (index != 0 && heap[parentIndex] < heap[index]) { swap(parentIndex, index); shiftup(parentIndex); } } function shiftDown(index) { let leftNodeIndex = (index + 1) * 2 - 1, rightNodeIndex = (index + 1) * 2 if (leftNodeIndex < heap.length && heap[leftNodeIndex] > heap[index]) { swap(leftNodeIndex, index); shiftDown(leftNodeIndex); } if (rightNodeIndex < heap.length && heap[rightNodeIndex] > heap[index]) { swap(rightNodeIndex, index); shiftDown(rightNodeIndex); } } function insert(val) { heap.push(val); shiftup(heap.length - 1); } function remove() { swap(0, heap.length - 1); let temp = heap.pop(); shiftDown(0); return temp; }