演算法筆記 資料結構 堆

2022-02-19 08:21:04 字數 2941 閱讀 2625

堆是一棵完全二叉樹,樹中每個結點的值都不小於(或者不大於)其左右孩子結點的值

對於給定初始序列,如何建堆?

給定陣列 [85, 55, 82, 57, 68, 92, 99, 98, 66, 56]
建堆過程如下

利用陣列來儲存完全二叉樹,這樣結點就按層序儲存與陣列中,其中第乙個結點將儲存於陣列的1號位,並且陣列i號位表示的結點的左孩子就是2i號位,右孩子是2i+1號位

const int maxn = 100;

// heap為堆,n為元素個數

int heap[maxn], n = 10;

回顧之前的建堆過程會發現,每次調整都是把結點從上往下的調整。針對這種向下調整,調整方法是這樣的:總是將當前結點v與它的左右孩子比較(如果有的話),假如孩子中存在權值比結點v的權值大的,就將其中權值最大的那個孩子結點與結點v交換;交換完畢後繼續讓結點v和孩子比較,直到結點v的孩子的權值都比結點v的權值小或是結點v不存在孩子結點。時間複雜度為o(logn)

// 對heap陣列在[low, high]範圍進行向下調整

// 其中low為欲調整結點的陣列下標,high一般為堆的最後乙個元素的陣列下標

void downadjust(int low, int high)

if(heap[j] > heap[i])else}}

假設序列中元素的個數為n,由於完全二叉樹的葉子結點個數為\(\left \lceil \frac \right \rceil\),因此陣列下標在\([1, \left \lfloor \frac \right \rfloor]\)範圍內的結點都是非葉子結點,於是從\(\left \lfloor \frac \right \rfloor\)位置開始倒著列舉結點,對每個遍歷到的結點i進行[i, n]範圍的調整。倒著列舉是因為每次調整完乙個結點後,當前子樹中權值最大的結點就會處在根結點的位置,這樣當遍歷到其父親結點是,就可以直接使用這個結果,保證每個結點都是以其為根結點的子樹中的權值最大的結點建堆的時間複雜度為o(n)

void createheap()

}

只要最後乙個元素覆蓋堆頂元素,然後對根結點進行調整即可,時間複雜度為o(logn)

void deletetop()
把想要新增的元素放在陣列最後,然後進行向上調整操作。向上調整總是把欲調整結點與父親結點比較,如果權值比父親結點大,那麼就交換其與父親結點,這樣反覆比較,直到到達堆頂或是父親結點的權值較大為止。向上調整的時間複雜度為o(logn)

void upadjust(int low, int high)else}}

所以,新增元素**:

void insert(int x)
堆排序是指使用堆結構對乙個序列進行排序

學習筆記 資料結構 堆結構

堆結構 實質是陣列 特點 以陣列的形式去儲存完全二叉樹 原理 以前序遍歷完全二叉樹,得出結點的前序序列,以陣列的形式儲存該序列。查詢父,子結點通過陣列下標id間的轉換關係實現。優點 節省儲存空間,查詢效率高 缺點 1 只能表示完全二叉樹 更廣泛的可以說是完全n叉樹 2 對樹的插入,刪除操作執行效率低...

演算法筆記 資料結構 棧

在之前,學過了stl的stack容器,所以以上函式可以通過庫呼叫 但是stl中沒有實現清空函式,所以如果需要實現棧的清空,可以用乙個while迴圈反覆pop出元素直到棧空 while st.empty codeup 1918 簡單計算器題目描述 讀入乙個只包含 的非負整數計算表示式,計算該表示式的值...

筆記 資料結構 演算法7

鄰接矩陣適用於稠密圖 邊數接近於頂點數的平方 鄰接表適用於稀疏圖 邊數遠小於頂點數的平方 鄰接矩陣取決於點,因此用於稠密圖,鄰接表用於稀疏圖,稠密圖用鄰接表表示的話會占用很多空間,而鄰接矩陣的空間是固定的都是n 所以用矩陣表示稠密圖。用鄰接矩陣法儲存乙個圖時,在不考慮壓縮儲存的情況下,所占用的儲存空...