堆中的路徑 小頂堆的建立以及堆排序

2022-07-25 05:39:08 字數 2433 閱讀 6699

推排序中的小頂堆的建立,需要注意的是,哪怕是相同的數,不同的插入順序最終建立堆都不一樣。

將一系列給定數字插入乙個初始為空的小頂堆h[i]。隨後對任意給定的下標i,列印從h[i]到根結點的路徑。

組測試第1行包含2個正整數n和m(≤1000),分別是插入元素的個數、以及需要列印的路徑條數。下一行給出區間[-10000, 10000]內的n個要被插入乙個初始為空的小頂堆的整數。最後一行給出m個下標。

對輸入中給出的每個下標i,在一行中輸出從h[i]到根結點的路徑上的資料。數字間以1個空格分隔,行末不得有多餘空格。

5 3

46 23 26 24 10

5 4 3

24 23 10

46 23 10

26 10

完全二叉樹,所以顯然使用陣列進行儲存。

前言也提到了,就算是相同的陣列序列,不同的插入順序,最終出來的堆都可能不一樣。所以不能直接對完整序列進行處理,需要乙個個插入操作。

小頂堆的插入是這樣的:

每次插入在接在最下層的空位的最右邊,然後再進行調整;

調整的時候從按照從下到上,從右到左的順序對非葉結點進行調整(這是因為葉結點顯然滿足小頂堆的要求)。每次調整目的都是要保證根結點比孩子結點小,如果不滿足,就與孩子結點中更小的那乙個互換,然後再對換下去的結點檢查並調整直至到底層或者滿足。

每次插入都會影響整體的樹,所以所有的非葉結點都需要進行調整。

訪問指定下標的路徑,且從底到上的方法:

因為使用陣列儲存,所以很方便的就可以找到某個結點的孩子結點,或者,某個結點的父結點。對於某個下標為i的結點來說,i/2向下取整就是該結點的父結點的位置。

注意,用陣列儲存二叉樹時最好從下標1開始儲存,因為可以方便的裡面上述性質。

#include#includeusing namespace std;

const int maxsize = 1001;

void myinsert(int a, int p, int key); //插入結點並執行調整程式

void mybuildheap(int a, int n); //對整棵樹進行調整,即對所有非葉結點進行調整操作

void myadjust(int a, int low, int high); //對單個非葉結點進行調整操作

void myshowpath(int a, int p); //找到並顯示路徑

int main() ;

int n, m;

cin >> n >> m;

for (int i = 1; i < n + 1; i++)

//到這裡已經建堆完成了

for (int i = 0; i < m; i++)

return 0;

}void myinsert(int a, int p, int key)

void mybuildheap(int a, int n)

void myadjust(int a, int low, int high)

else

break; }}

void myshowpath(int a, int p)

cout << endl;

}

絕對的核心演算法,這裡有以下幾個點需要注意的:

對於小頂堆而言,只需要將父結點與子結點內更小的那個進行比較即可,不需要兩個全部比較,調換的話也只需要與更小的那個呼喚即可

需要考慮到該非葉結點可能只有乙個子結點的情況,因為ct的特殊性質,如果存在這種結點,其子結點位置必然處於最後乙個位置,且肯定是左結點,只要對這個進行判斷即可

若是一輪迴圈中沒有發生互換,說明整棵樹已經調整好了,因為從下往上調整的,所以底下的肯定也是調整好的

void myadjust(int a, int low, int high) 

else

break; //如果這輪不發生更換的話,那說明整棵樹已經調整好了,因為從下往上調整的,所以底下的肯定也是調整好的

}}

都說到小頂堆的建立了,怎麼能不加上推排序呢。

小頂堆的性質是根結點的數必定是整個樹中最小的。

推排序就是每次將根結點的數與末尾的數提取出來,並將最後乙個葉結點的數填充到根結點的位置再對根結點進行調整使其再次稱為小頂堆,直至最後將所有元素按照順序提取出來,就是乙個有序序列了。

所以在建好堆之後加乙個提取過程就行了

排序順帶輸出了

void myheapsort(int a, int n) 

cout << endl;

}void myswap(int a, int x, int y)

堆排(大頂堆,小頂堆)

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

堆中的路徑(構建小頂堆)

將一系列給定數字插入乙個初始為空的小頂堆h。隨後對任意給定的下標i,列印從h i 到根結點的路徑。每組測試第1行包含2個正整數n和m 1000 分別是插入元素的個數 以及需要列印的路徑條數。下一行給出區間 10000,10000 內的n個要被插入乙個初始為空的小頂堆的整數。最後一行給出m個下標。對輸...

小頂堆及大頂堆的建立

首先明確堆是乙個完全二叉樹,小頂堆指根結點的值小於或等於左右子節點的值,大頂堆指根結點的值都大於或等於左右子節點的值 關於大小頂堆的建立更詳細的介紹 include include include include include include include include using names...