堆 優先順序佇列

2021-10-06 15:13:06 字數 3493 閱讀 1205

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...