建立最小堆,依次刪除堆頂元素值,實現從小到大的堆排序。
堆排序的時間複雜度是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,這個很顯然。然後會發現乙個問題,每次割草時,不知道從 開始...