堆排列 手寫堆

2021-10-02 13:52:02 字數 2953 閱讀 1559

簡單來說堆就是維護乙個資料集合,堆的實質是乙個二叉樹;

堆的性質:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆。

附上圖 嘿嘿~:

今天我們說的小頂堆的堆排列介個問題(我才不會告訴你們我只學了小頂堆~小聲bb)~~

(這裡說一下,因為我們這次是手寫堆的教程,跟stl中堆有所不同,4、5操作在stl中是無法完成的,,,還有就是儲存問題

stl中堆是使用優先佇列進行儲存;

手寫堆是使用乙個一維陣列進行儲存;(嗯,對的 ,乙個一維陣列;)

(一般為了方便會把根節點記為1而不是0)

在陣列中儲存的位置一般就是,第乙個為根節點,接下來是根節點的左兒子,,,

(簡單來說就是我們第x位置存放根節點的話

它的左兒子為 第2x個位置;

右兒子 第2x+1個位置;

)主要就是兩個操作down(x)還有up(x)

所謂 down(x);

就是從上到下進行處理;

舉個栗子~~

若將 1處位置—>4改為10

此時與堆的性質不符,將1處與其左右兒子相比較,找出最小值,交換兩處位置,(因為堆頂為最小值)

同理與2處與其左右兒子相比較,,最總結果為:

同理up(x)操作為從下到上搜尋

例如

5處9改為—>2;

與down不同,up只與其父節點比較,,,

2<8 將3處5處交換

繼續向上搜尋 2<4 交換1處3處

結束;

// h[n]儲存堆中的值, h[1]是堆頂,x的左兒子是2x, 右兒子是2x + 1

// ph[k]儲存第k個插入的點在堆中的位置

// hp[k]儲存堆中下標是k的點是第幾個插入的

int h[n]

, ph[n]

, hp[n]

, size;

// 交換兩個點,及其對映關係

void

heap_swap

(int a,

int b)

void

down

(int u)

}voidup(

int u)

}// o(n)建堆

for(

int i = n /

2; i; i --

)down

(i);

好,接下來我們康康主要問題

主要包括以下5個問題

1.插入乙個數x;

插入乙個數從末尾插入:

h[

++size]

=x;

2.求集合中的最小值最小值就是根節點

h[

1]

3.刪除最小值刪除事就是用最末尾元素覆蓋第乙個然後down

h[1]

=h[size]

;size--

;down(1

);

4.刪除任意乙個元素(刪除第x個)刪除也是用末尾元素覆蓋這個元素,,但這個元素需要判斷,,這裡有個簡單的辦法就是down 與up都操作一次,,,主意在執行的時候只會選擇其一

h[x]

=h[size]

;size--

;down

(x);

up(x)

;

5.修改任意乙個元素(第x個改為xx)與第四個差不多;

h[x]

=xx;

down

(x);

up(x)

;

就介個樣子吧

貼個題;

堆排序ac**

#include

#include

using

namespace std;

const

int n=

1e5+6;

int h[n]

;int n,m;

int siz;

void

down

(int u)

}int

main()

return0;

}

第一次寫多多包涵大家都不容易

哦了,拜拜~~

堆的基本操作 手寫模擬堆

解析 這個題比較麻煩的一點就是k。第k個插入的數,不是樹里的序號。經過一系列變換後,第k個插入的數在樹里的序號會發生交換。所以引入兩個陣列 ph i x 表示第i次插入的數,在樹中的序號為x。hp i x 表示樹中的序號i,是第x次插入的數。乍一看,hp似乎並沒有什麼用,每次交換h和ph即可了。別急...

優先佇列 (乾掉手寫堆 嗚嗚嗚 )

優先佇列中的元素會按某種優先順序依次出佇列,即可實現按此優先順序排序,時間複雜度和堆排序差不多 1.priority queueq 預設優先順序從到大到小 priority queue,greater q 優先順序從小到大 2.除此之外我們還可以選擇過載運算子 用於結構體 無法直接定義 includ...

堆排(大頂堆,小頂堆)

分類 資料結構 演算法相關 2009 10 15 12 26 2289人閱讀收藏 舉報汗,別人都說大小頂堆只是改改大於號的問題,可我的 從大頂堆只改動大於號調整為小頂堆竟然越界樂,掣肘!後來幾經更改才發現是傳參的問題 見 看來大頂堆改小頂堆不是 亦或是我rp出點問題?搞笑的是 磚頭 c b 竟然對越...