進擊的堆 最大索引堆

2021-08-28 14:57:04 字數 3086 閱讀 2946

文章儲存在github,網速不佳的朋友,請看《進擊的堆:最大索引堆》 或者 來我的技術小站 godbmw.com

堆結構的資料增刪操作,需要swap操作。雖然可以被優化成每次一次賦值,然而當元素型別是複雜資料機構(例如:類、浮點數、結構體等),賦值操作的消耗不容小覷。

因此,如果可以通過交換整數資料,來實現堆的資料操作,就會大大提高程式效能。而索引堆就是為此而生。

在堆的基礎上,增加乙個整數陣列indexes

indexes[i]就代表:堆中第 i 個元素在所屬陣列中的位置。

如下圖所示,index[1]代表堆中的第 1 個元素是data中的第 10 個元素。

因此,有了indexes陣列,data陣列不要變動,只需要維護indexes陣列即可表示堆中的資料順序。

當我們需要改變原來data陣列中的乙個資料並且維護堆的結構,需要反向索引來幫助。

堆中引入reverse陣列。reverse[i]代表索引 i 在indexes陣列的位置。

如下圖所示,reverse[1]代表 1 在indexes中的位置是 8。

借助反向查詢,當我們修改第 9 個元素的時候,訪問reverse[9]便可以知道data[9]在堆中的位置是 2。時間複雜度降低到o(1)

為了方便理解,請看後面實現的maxindexheap.h中的void change(int i, item new_item)函式。

maxindexheap.h**如下:

//

// created by godbmw.com on 2018/9/26.

//#ifndef maxheap_indexmaxheap_h

#define maxheap_indexmaxheap_h

#include

#include

#include

#include

using

namespace std;

template

<

typename item>

class

indexmaxheap

}void

shift_down

(int k)

if(data[indexes[k]

]>= data[indexes[j]])

swap

(indexes[k]

, indexes[j]);

reverse[indexes[k]

]= k;

reverse[indexes[j]

]= j;

k = j;}}

public

:indexmaxheap

(int capacity)

this

->count =0;

this

->capacity = capacity;}~

indexmaxheap()

// 返回堆中元素個數

intsize()

// 返回布林值:堆中是否為空

bool

is_empty()

// 向堆中插入元素item, i是元素索引

void

insert

(int i, item item)

// 取出最大值

item extract_max()

intextract_max_index()

bool

contain

(int i)

item get_item

(int i)

void

change

(int i, item new_item)

// }

// 利用 reverse 實現反向查詢, 從 o(n) => o(1)

int j =

this

->reverse[i]

;this

->

shift_up

(j);

this

->

shift_down

(j);}}

;#endif

//maxheap_indexmaxheap_h

main.cpp**如下:

#include

#include

#include

#include

"maxheap.h"

#include

"indexmaxheap.h"

#include

"sorthelper.h"

#define heap_capacity 10

#define max_num 100

using

namespace std;

intmain()

cout<

index_max_heap.

change(1

,109);

while

(!index_max_heap.

is_empty()

) cout<

return0;

}

java實現最大索引堆 最大堆的優化版

最大索引堆是為了防止swap 交換大型資料帶來的低效率,所以只交換索引。所以成員變數上比最大堆多了乙個儲存索引的陣列indexs,為了更方便快捷找到某個索引在indexs中的位置,因此又新增了乙個儲存索引位置的陣列reverse,reverse i 的值表示索引i在indexs j i中的位置j 即...

索引堆的優化

之前的change函式如下 希望將索引為i的元素的值修改為 newitem void change int i,item newitem 優化思路 實現 include include include include include include include include using nam...

02 索引 堆表

堆表查詢 首先在沒有任何索引的情況下檢視 分頁情況 select database id index id index type desc index depth index level page count from sys.dm db index physical stats db id ind...