C語言 堆與完全二叉樹與優先佇列

2021-10-10 08:40:29 字數 1934 閱讀 9150

堆與完全二叉樹區別:堆分為大頂堆和小頂堆,即在滿足完全二叉樹的條件下,還要滿足(根,左孩子, 右孩子)這個三元組始終滿足根最大or最小的性質。

接下來,以大頂堆為例,闡述關於堆的一些操作:

查詢最值:根始終為最大值,根的左右孩子中一定有第二大值,但第三大值就不確定了;

插入值:首先為了滿足完全二叉樹的結構,將值新增在最後面,然後沿著該節點到根的這條路勁上,以從小到大的原則,進行換位調整(有點冒泡的意思),直到整條路徑上的元素為有序的;

彈出值:將棧頂彈出(類似佇列),然後為了維護完全二叉樹節構,將樹最後元素交換到根,然後自上而下檢索三元組是否滿足要求,若不符合,繼續將根結點與左右子樹中的最值交換;

總體來說,堆是乙個 插入尾部,彈出頭部 的結構,這符合fifo(佇列)的性質,並且彈出的值有最值性質,所以又稱該結構為優先佇列。

由於堆的優先佇列性質,可以通過堆來實現堆排序

排序過程以大頂堆為例,每次堆頂彈出當前佇列最大值,並將隊尾元素交換到堆頂,然後檢查有序性。那麼如果利用佇列原本的儲存空間,可以將每一次彈出操作,視為隊首與隊尾的一次交換,每次交換後,佇列元素數量減一,這樣,彈出的最大值、次大值…就會被安放在陣列的n-1、n-2、…位置上,最後整個陣列是按從小到大排序的。

#include

#include

#include

#define swap(a, b)

typedef

struct priority_queuepriority_queue;

priority_queue *

init

(int n)

intempty

(priority_queue *q)

inttop

(priority_queue *q)

intpush

(priority_queue *q,

int val)

return1;

}//彈出元素在隊尾後面

intpop

(priority_queue *q)

return1;

}void

clear

(priority_queue *q)

intmain()

printf

("q:");

for(

int i =

0; i < max_n; i++

)printf

("\n");

for(

int i =

0; i < max_n; i++

)#undef max_n

clear

(q);

}

//線性建堆

#include

#include

#define swap(a, b) __typeof(a) t = a; a = b; b = t

void

downupdate

(int

*arr,

int n,

int ind)

return;}

void

heap_sort

(int

*arr,

int n)

//用堆排序

for(

int i = n; i >

1; i--

)return;}

intmain()

;heap_sort

(arr,6)

;for

(int i =

0; i <

6; i++

)}

二叉堆 完全二叉樹 優先佇列

完全二叉樹的邏輯結構是樹結構,但由於其特殊性,資料結構中常用陣列來儲存.訪問父節點,左子結點,右子節點都很方便 陣列儲存以1為起點 假設有某一結點u a u 2 為其父節點,當且僅當u 1 a u 2 為其左子結點,當且僅當u 2 n a u 2 1 為其右子節點,當且僅當u 2 1 n inclu...

二叉堆(完全二叉樹)

最小堆的實現 最小堆是一顆完全二叉樹 這裡用陣列實現完全二叉樹 index 0 1 2 3 4 5 6 value 空 a b c d 任意index,其父親為index 2,左兒子為2 index,右兒子為2 index 1 時間複雜度 o logn include includeusing na...

與滿二叉樹完全二叉樹

去寫很多,每個已對二進位制樹的主題,其中大部分都在完全二叉樹,在哥斯大黎加的心臟完全然而二叉樹一直很模糊的形式,原因是,我完全糊塗了二進位制和滿二叉樹。實際上滿二叉樹是二叉樹的一種特殊情況完全,由於滿二叉樹滿。雖然完全不能代表全。所以,你應該想象塑造出它,外每乙個節點都有兩個孩子。而全然的含義則是最...