Skip to content

Commit fe1e031

Browse files
committed
add indexMaxHeap
1 parent a129166 commit fe1e031

3 files changed

Lines changed: 133 additions & 1 deletion

File tree

‎JavaScript/Heap/IndexMaxHeap.js‎

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* 索引堆
3+
*/
4+
module.exports.IndexMaxHeap = class IndexMaxHeap {
5+
constructor() {
6+
this.data = []; // 最大索引堆中的数据
7+
this.index = []; // 最大索引堆中的索引
8+
this.count = 0;
9+
}
10+
init() {
11+
12+
}
13+
// 提升子元素
14+
// 索引堆中,数据之间比较根据data大小进行比较,但实际操作是索引
15+
shiftUp(k) {
16+
var p = Math.floor((k-1)/2); // 父元素对应索引
17+
while(k > 0 && this.data[this.index[p]] < this.data[this.index[k]]) {
18+
this.swap(this.index, p, k);
19+
k = p;
20+
p = Math.floor((k-1)/2);
21+
}
22+
}
23+
// 索引堆中,数据之间比较根据data大小进行比较,但实际操作是索引
24+
shiftDown(k) {
25+
while((2*k+1) < this.count) {
26+
var j = 2 * k + 1;
27+
if(j+1 < this.count && this.data[this.index[j+1]] > this.data[this.index[j]]) {
28+
j++;
29+
}
30+
if(this.data[this.index[k]] >= this.data[this.index[j]]) break;
31+
this.swap(this.index, k, j);
32+
k = j;
33+
}
34+
}
35+
// 向最大堆中插入一个新元素
36+
insert(element) {
37+
var i = this.index.length;
38+
this.data.push(element);
39+
this.index.push(i);
40+
this.count++;
41+
this.shiftUp(i);
42+
}
43+
// 从最大索引堆中取出堆顶元素,即索引堆中所存储的最大数据
44+
extractMax() {
45+
var ret = this.data[this.index[0]];
46+
this.swap(this.index, 0, this.count-1);
47+
this.count--;
48+
this.shiftDown(0);
49+
return ret;
50+
}
51+
// 从最大索引堆中取出堆顶元素索引
52+
extractMaxIndex() {
53+
var ret = this.index[0];
54+
this.swap(this.index, 0, this.count-1);
55+
this.count--;
56+
this.shiftDown(0);
57+
return ret;
58+
}
59+
// 获取最大索引堆中的堆顶元素
60+
getMax() {
61+
return this.data[this.index[0]];
62+
}
63+
// 获取最大索引堆中的堆顶元素的索引
64+
getMaxIndex() {
65+
return this.index[0];
66+
}
67+
// 获取最大索引堆中索引为i的元素
68+
getItem(i) {
69+
return this.data[i];
70+
}
71+
// 修改最大索引堆中索引为i的元素
72+
change(i, newElement) {
73+
data[i] = newElement;
74+
for(var j = 0; j < this.count; j++) {
75+
if(this.index[j] === i) {
76+
this.shiftUp(j);
77+
this.shiftDown(j);
78+
return;
79+
}
80+
}
81+
}
82+
// 返回索引堆中的元素个数
83+
size() {
84+
return this.count;
85+
}
86+
// 判断当前索引堆是否为空
87+
isEmpty() {
88+
return this.count === 0;
89+
}
90+
swap(arr, a, b) {
91+
var t = arr[a];
92+
arr[a] = arr[b];
93+
arr[b] = t;
94+
}
95+
}
96+
97+
// 使用最大索引堆进行排序
98+
// 最大索引堆的主要作用不是用于排序,而是在最小生成树,最短路径算法中起到优化作用
99+
module.exports.indexMaxHeapSort = function indexMaxHeapSort(arr) {
100+
var indexMaxHeap = new exports.IndexMaxHeap();
101+
for(var i = 0; i < arr.length; i++) {
102+
indexMaxHeap.insert(arr[i]);
103+
}
104+
for(var i = arr.length-1; i >= 0;i--) {
105+
arr[i] = indexMaxHeap.extractMax();
106+
}
107+
}

‎JavaScript/Heap/MaxHeap.js‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,23 @@ module.exports.maxHeap = class MaxHeap {
6161
k = j;
6262
}
6363
}
64+
// 优化shiftDown,使用赋值的方式取代不断的swap
65+
// 优化思路借鉴插入排序的优化思路
66+
shiftDownII(k) {
67+
// 先保持k索引对应的值
68+
var t = this.data[k];
69+
while(2*k+1 <= this.count-1) {
70+
var j = 2 * k + 1;
71+
if(j+1 <= this.count-1 && this.data[j+1] > this.data[j]) {
72+
j++;
73+
}
74+
if(t > this.data[j]) break;
75+
arr[k] = arr[j];
76+
k = j;
77+
}
78+
// 最后再赋值
79+
this.data[k] = e;
80+
}
6481
// 从最大堆中取出堆顶元素,即堆中所存储的最大数据
6582
extractMax() {
6683
if(this.count <=0) return;
@@ -105,4 +122,4 @@ module.exports.heapSort2 = function heapSort2(arr) {
105122
for(var i = arr.length-1; i >= 0; i--) {
106123
arr[i] = maxHeap.extractMax();
107124
}
108-
}
125+
}

‎JavaScript/Heap/Test.js‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,11 @@ console.log(arr1);
2222
var arr2 = [1, 8, 9, 2, 4, 5, 10, 21];
2323
heap.heapSort2(arr2);
2424
console.log(arr2);
25+
26+
// 测试最大索引堆
27+
console.log("==========测试最大索引堆=================");
28+
var indexMaxHeap = require('./IndexMaxHeap');
29+
var arr3 = [1, 8, 9, 2, 4, 5, 10, 21];
30+
indexMaxHeap.indexMaxHeapSort(arr3);
31+
console.log(arr3);
32+

0 commit comments

Comments
 (0)