堆與完全二叉樹區別:堆分為大頂堆和小頂堆,即在滿足完全二叉樹的條件下,還要滿足(根,左孩子, 右孩子)這個三元組始終滿足根最大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...
與滿二叉樹完全二叉樹
去寫很多,每個已對二進位制樹的主題,其中大部分都在完全二叉樹,在哥斯大黎加的心臟完全然而二叉樹一直很模糊的形式,原因是,我完全糊塗了二進位制和滿二叉樹。實際上滿二叉樹是二叉樹的一種特殊情況完全,由於滿二叉樹滿。雖然完全不能代表全。所以,你應該想象塑造出它,外每乙個節點都有兩個孩子。而全然的含義則是最...