演算法設計和資料結構學習 1 一道堆排序作業題

2021-07-22 17:16:18 字數 3428 閱讀 4356

前言

這時上次學妹課程的一道作業題,我花了點時間做了下,其題目內容為:

試寫一程式,可以對一二元樹(binary)進行堆積排序(heap sort)

(a)使用者可自己決定輸入二元樹的節點個數

(i)node數不超過50

(b)節點值由隨機方式產生,並印出隨機設值結果

(i)以時間複雜度o(n)的方式設值 (ii)假設值不可重複

(iii)最大值不可大於node數 (例如node數為9,因此最大值為9)

(c)使用者可決定使用max-heap或者是min-heap來排序

(d)須將重建堆積得過程印出,以及最後輸出排序結果

後面在網上查了下堆排序的介紹,才對堆有了一點理解。其定義為:堆是一種近似完全二叉樹的結構,並滿足堆性質,即子節點的鍵值索引總是小於(或大於)它的父節點。因此堆的任何一顆子樹仍然是堆。

實驗說明

堆排序的步驟為:

a. 按照大堆或者小堆的方式將輸入進來的陣列初始化為對應的堆。在此過程中先從最後乙個非葉子節點開始慢慢後退到根節點,有點遞迴的味道,因為一旦乙個節點的2個子節點樹都進行了堆初始化後,父節點和子節點即使不滿足堆對關係,也只需要調換其中乙個位置再重新初始化過,而另乙個子樹就無需堆初始化了(每個子節點的其中乙個樹都無需堆初始化),這樣比較節省演算法的速度。

b. 交換堆中跟節點和最後乙個未排序的節點的位置,然後繼續將參與排序的樹進行步驟a的堆形式初始化。

產生不重複的隨機數,且需要滿足它的時間複雜度為o(n),這是本題比較刁難的地方。我這裡採用方法是:對需排序的陣列產生同樣大小的標記陣列,如果對應位置的數字已經經過隨機數發生器產生過,則標誌設定為1,否則設定為0,以後每當產生乙個隨機數,只需判斷其對應位置的標誌而已,這一操作的時間複雜度為o(1),所以產生n個不重複的隨機數的時間複雜度為o(n),其本質是利用空間來換取時間。

c/c++知識總結:

doublefloor (doublex );  

該函式返回不大於x的最大整數,c/c++中有該函式的存在,如果x是正實數,則返回的整數字x去掉小數的部份。如果x是負實數,則返回的是x去掉小數點後繼續減1。

實驗結果

採用大端模式對10個數字進行堆排序的結果為:

採用小端模式對10個數字進行堆排序的結果為:

實驗**:

#include #include 

#include

using

namespace

std;

#define max_heap_mode 0

#define min_heap_mode 1unsigned

int heap_node_number = 20

;bool heap_sort_mode = max_heap_mode;//

預設為大堆排序模式

char choose_sort_mode; //

手動輸入選擇小端大端模式的變數

vectorheap_tree;

/****

*產生不重複的隨機數,且要滿足時間複雜度為o(n)

*因此不能夠每次產生乙個隨機數後,依次與前面已經產生過的隨機數做比較了,因為這樣的時間複雜度為o(n*n)

*因此本函式採用的方法是以空間換時間,多建立乙個vector,用來儲存對應的標誌位,如果對應數字已經產生了

*則無需再產生,這樣的話每次判斷只有1下,即每次判斷的時間複雜度為o(1),產生n個隨機數的時間複雜度就為o(n)了

****/

void generaterandomnumber(vector &create_rand_num, int

num)

}}/*

*** *人機互動的輸入輸出初始化函式

****/

void

init()

else

cout

<

cout

<< "

請選擇堆排序模式(a)max mode, (b)min mode: ";

cin >>choose_sort_mode;

if(choose_sort_mode == '

a' || choose_sort_mode == 'a'

)

else

if(choose_sort_mode == '

b' || choose_sort_mode == 'b'

) generaterandomnumber(heap_tree, heap_node_number);

cout

<< "

二元樹的內容:

"<

for(int i = 0; i < heap_tree.size(); i++)

cout

<< "

"<< endl <

*** *輸出堆排序的中間過程

****/

display_mode)

/****

*該函式的功能是:將heap_tree指定的位置節點select_node開始的子樹調整為堆

*的形式,其結果仍然保留在heap_tree樹中。

*該函式的呼叫必須配合select_node節點的子樹本身已經滿足堆的形式,也就是說該函式是

*數heap_tree從底往上被呼叫的

****/

void adjustchildheaptree(vector &heap_tree, int select_node, int len, bool

heap_sort_mode) }}

else

if(1 ==heap_sort_mode) }}

return;}

void heapsort(vector &heap_tree, bool

heap_sort_mode)

}int

main()

演算法設計和資料結構學習 1 一道堆排序作業題

前言 這時上次學妹課程的一道作業題,我花了點時間做了下,其題目內容為 試寫一程式,可以對一二元樹 binary 進行堆積排序 heap sort a 使用者可自己決定輸入二元樹的節點個數 i node數不超過50 b 節點值由隨機方式產生,並印出隨機設值結果 i 以時間複雜度o n 的方式設值 ii...

演算法設計和資料結構學習 1 一道堆排序作業題

前言 這時上次學妹課程的一道作業題,我花了點時間做了下,其題目內容為 試寫一程式,可以對一二元樹 binary 進行堆積排序 heap sort a 使用者可自己決定輸入二元樹的節點個數 i node數不超過50 b 節點值由隨機方式產生,並印出隨機設值結果 i 以時間複雜度o n 的方式設值 ii...

演算法和資料結構學習筆記

演算法和資料結構就是程式設計的乙個重要部分,你若失掉了演算法和資料結構,你就把一切都失掉了。一 資料結構和演算法緒論 說說資料結構 程式設計 資料結構 演算法 再簡單來說,資料結構就是關係,也就是資料元素相互之間存在的一種或多種特定關係的集合。資料結構的分類 傳統上,我們把資料結構分為邏輯結構和物理...