aha7神奇的樹

2021-10-19 02:42:19 字數 2295 閱讀 3168

建立最小堆,依次刪除堆頂元素值,實現從小到大的堆排序。

堆排序的時間複雜度是0(nlogn)。

堆是乙個父結點大於等於(小於等於)左右子結點的完全二叉樹。

//堆排序-從小到大排序建立最小堆

#include

#include

using namespace std;

int h[

101]

;//存放堆的陣列

int n;

//存放堆的大小

//向下調整函式

void

siftdown

(int i)

//傳入需要向下調整的結點編號i

//如果最小結點編號!=i

if( t != i)

else

flag =1;

}}//建立堆

void

creat()

}//刪除最小的元素

int deletemin()

int main()

n = num;

creat()

;//建堆

for(int i=

1; i<=num; i++

)//從小到大輸出堆頂值

堆排序還有一種更好的方法:建立最大堆,並依次將h[1]和h[n]交換,此時h[n]就是陣列中最大的元素。交換後需要將h[1]向下調整保持堆的特性。將堆的大小依次減一即n–,再將h[1]和h[n]交換,將h[1]向下調整。直到堆大小為1,此時h陣列就是排好序的數。

//堆排序-從小到大排序建立最大堆

#include

#include

using namespace std;

int h[

101]

, n;

void

siftdown

(int i)

if(t != i)

else

flag =1;

}}void

creat()

}//堆排序

利用堆排序求數列中第k大或第k小的數。

//求數列中第k小的數

#include

#include

#include

using namespace std;

int finfkthsmallest

(vector

& nums, int k)

elseif(

q.top(

)>nums[i])}

returnq.

top();

}int main()

printf

("%d"

,finfkthsmallest

(nums,3)

);return0;

}

以上**參考:

//並查集

#include

int f[

1000]=

, n, m, k, sum=0;

//f陣列初始化

void

init()

//找祖宗

int getf

(int v)

else

}//靠左原則

線段樹,樹狀陣列,trie樹(字典樹),二叉搜尋樹,紅黑樹(一種平衡二叉搜尋樹)等。

《啊哈!演算法》第7章 神奇的樹

把n個元素建立乙個堆,首先將這n個結點以自頂向下 從左到右的方式從1到n編碼,這樣可以把n個結點轉換成一顆完全二叉樹 緊接著從最後乙個非葉子結點 結點編號為n 2 開始到根節點 結點編號為1 逐個掃瞄所有結點,根據需要將當前結點向下調整,直到以當前結點為根結點的子樹符合堆的特性。include in...

模擬 神奇的樹

time limit 1000ms memory limit 65536k sdut有一顆神奇的蘋果樹。假如某天早上這樹上有x個蘋果,那麼這樹這一天會再結出x個蘋果來,也就是說到了晚上會有2 x個蘋果,到了深夜,會有專人人來摘蘋果,而摘蘋果的人總會使蘋果數剩下當前數量對m的餘數,也就是說假如當前數量...

火星補鍋 siano 神奇的線段樹

本來以為很難打的,沒想到主幹一次就打對了,然而把輸入的b和d弄混了,這sb錯誤調了兩個小時。神奇的線段樹。注意到有乙個性質,無論怎麼割草,生長速度快的一定不會比生長速度慢的矮。因此可以先排個序,然後就可以用線段樹維護了。首先維護區間的sum,這個很顯然。然後會發現乙個問題,每次割草時,不知道從 開始...