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+ }
0 commit comments