1一般二叉樹的順序儲存(層序遍歷方式): 使用陣列儲存二叉樹結構,即將二叉樹 按照層序遍歷 的方式放入陣列.這種方式一般只適用於完全二叉樹,一般的二叉樹會造成空間浪費比較嚴重.
2堆(heap) 在邏輯上就是乙個 完全二叉樹, 在物理上儲存在 陣列 中.
(1) 滿足任意結點的值都大於其子樹的結點的值. 叫做大堆, 反之是小堆.
(2) 作用: 快速找到 集合中的最值.
3堆中元素下標關係. 已知父親(parent)的下標, 或已知左右孩子(child)下標時:
(1) 當根節點下標 從0開始計算時, 左孩子(left)下標 = 2 × parent + 1, 右孩子(right)下標 = 2 × parent + 2. 雙親下標(不區分左右子樹) = (child-1) / 2;
(2) 當根節點下標 從1開始計算時, 左孩子(left)下標 = 2 × parent, 右孩子(right)下標 = 2 × parent + 1. 雙親下標(不區分左右子樹) = child / 2;
4向下調整.
前提是 左右子樹必須已經是乙個堆, 才能進行調整.
(1) size 是array 中哪些元素是有效的堆元素, 即有效元素個數.
(2) index 表示開始調整的下標位置.
(3) 這裡以小堆為例, 根節點下標為0進行調整.
public
static
void
shiftdown
(int
array,
int size,
int index)
if(array[child]
< array[parent]
)else
// 更新 parent 和 child, 處理下一層的資料.
parent = child;
child =
2* parent +1;
}}
(4) 大堆向下調整.
public
static
void
shiftdown
(int
array,
int size,
int index)
if(array[child]
> array[parent]
)else
parent = child;
child =
2* parent +1;
}}
4建堆: 把乙個無序陣列建成乙個堆. 注意 建堆和堆排序沒有任何關係.
過程: 從後往前遍歷陣列, 找到 最後乙個非葉子結點, 然後開始進行向下調整. 時間複雜度為 (ologn). 以構建小堆為例:
建堆:找到最後乙個非葉子節點,然後進行向下調整操作,每次之後i--
public
static
void
createheap
(int
array,
int size)
}public
static
void
main
(string[
] args)
;createheap
(array, array.length)
; system.out.
println
(arrays.
tostring
(array));
}向下調整建好的小堆:[2
,3,6
,7,5
,9,8
]
5向下調整和向上調整的區別.
向下調整是 讓父節點作為起始點, 決定子節點下標, 然後向下進行調整, 即一次調整完後父節點 = 子節點.
向上調整是 讓子節點作為起始點, 決定父節點下標, 然後向上進行調整, 即一次調整完後子節點 = 父節點.
6優先順序佇列 (priorityqueue) 本質是乙個堆. 通常需要按照優先順序情況對處理物件進行處理, 比如首先處理優先順序最高的物件, 然後處理優先順序次高的物件. 也可以計算topk問題.
入佇列 (以大堆為例): 找到最後乙個 葉子節點進行 向上調整.
private
static
void
shiftup
(int
array,
int index)
else
child = parent;
parent =
(child -1)
/2;}
}
出佇列 (以大堆為例):用最後乙個元素替換隊首元素, 然後刪除最後乙個元素, 同時再進行 向下調整.
public
intpoll()
取隊首元素(優先順序最高) (以大堆為例):直接 返回堆頂元素.
public
intpeek()
7練習 (查詢和最小的k對數字). 給定兩個以公升序排列的整形陣列 nums1 和 nums2, 以及乙個整數 k, 查詢和最小的k對數字.
輸入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3.
輸出: [1,2], [1,4], [1,6]
class
pair
implements
comparable
@override
public
intcompareto
(pair o)
}public
class
heapexam
// 當前是需要前 k 小的元素, 就建立乙個小堆
priorityqueue
queue =
newpriorityqueue
<
>()
;// 採取第一種方式來做
for(
int i =
0; i < nums1.length; i++)}
// 迴圈結束之後, 此時所有數對都在佇列中, 迴圈取出 k 個較小元素即可
for(
int i =
0; i < k &&
!queue.
isempty()
; i++
)return result;
}}
堆(優先順序佇列)
c 的 stl 中提供了 優先佇列 這一容器,它和普通的 fifo 佇列都定義在 中,有 push 和 pop 過程,分別表示 往佇列裡加入新元素 和 從佇列裡刪除隊首元素 唯一的區別是,在優先佇列中,元素並不是按照進入佇列的先後順序排列,而是按照優先順序的高低順序排列 換句話說,pop 刪除的是優...
優先順序佇列 堆
1.1 堆的概念 堆邏輯上是一棵完全二叉樹 堆物理上是儲存在陣列中位元科技 滿足任意結點的值都大於其子樹中結點的值,叫做大堆,或者大根堆,或者最大堆 反之,則是小堆,或者小根堆,或者最小堆 堆的基本作用是,快速找集合中的最值 1.2儲存方式 使用陣列儲存二叉樹結構,方式是將二叉樹用層序遍歷方式放入陣...
優先順序佇列(堆)
2 堆 heap 3 優先順序佇列 使用陣列儲存二叉樹結構,方式即將二叉樹用層序遍歷方式放入陣列中。一般只適合表示完全二叉樹,因為非完全二叉樹會有空間的浪費。這種方式的主要用法就是堆的表示。已知雙親 parent 的下標,則 左孩子 left 下標 2 parent 1 右孩子 right 下標 2...