摘要:二叉堆的概念二叉堆是一種特殊的二叉樹(shù)。二叉堆分為兩種最大堆和最小堆,最大堆的父節(jié)點(diǎn)一定大于其子節(jié)點(diǎn)根節(jié)點(diǎn)最大,最小堆的父節(jié)點(diǎn)小于其子節(jié)點(diǎn)根節(jié)點(diǎn)最小。這是我對(duì)二叉堆的理解,如有不對(duì),歡迎指正,我會(huì)立即修改,謝謝。
二叉堆的概念
二叉堆是一種特殊的二叉樹(shù)。二叉樹(shù)是每個(gè)節(jié)點(diǎn)只有兩個(gè)子節(jié)點(diǎn)的樹(shù)(應(yīng)該都懂吧)。二叉堆分為 兩 種:最大堆和最小堆,最大堆的父節(jié)點(diǎn)一定大于其子節(jié)點(diǎn)(根節(jié)點(diǎn)最大),最小堆的父節(jié)點(diǎn)小于其子節(jié)點(diǎn)(根節(jié)點(diǎn)最小)。
下面是一個(gè)二叉樹(shù):
我們用一維數(shù)組將二叉樹(shù)初始化,例如:我們有{1,2,3,4,5,6,7}七個(gè)數(shù)要放入堆中,第一步初始化數(shù)組的長(zhǎng)度大于8,array[0]為null,array[1]~array[7]放入數(shù)字。
為什么array[0]為null呢?因?yàn)橐孟聵?biāo)值找到它的子節(jié)點(diǎn)和父節(jié)點(diǎn),比如a[1]=1,a[2]=2,a[3]。我們知道a[1]的子節(jié)點(diǎn)是a[2],a[3],由于是二叉樹(shù),a[k]的子節(jié)點(diǎn)一定是a[2k]和a[2k+1],a[k]的父節(jié)點(diǎn)一定是a[k/2]。花個(gè)20秒思考一下吧。
圖示:
將一個(gè)二叉樹(shù)變成二叉堆我以最大堆為例,最大堆的定義是:父節(jié)點(diǎn)的value一定要大于子節(jié)點(diǎn)的value。
1.子節(jié)點(diǎn)的value大于父節(jié)點(diǎn)的value的情況
此時(shí)T大于P,違反了最大堆的平衡性,所以要將T和其父節(jié)點(diǎn)對(duì)調(diào)
但是T移動(dòng)到了P的位置后,它的值依然比其父節(jié)點(diǎn)要大,還要上浮
最終T移動(dòng)到了根節(jié)點(diǎn),最大堆平衡了
代碼如下:
public void swim(int k) { while (k > 1 && less(k / 2, k)) { exch(k / 2, k); k = k / 2; } }
2. 父節(jié)點(diǎn)的value小于子節(jié)點(diǎn)的value的情況
此時(shí),H比子節(jié)點(diǎn)要小,H要下沉,先比較P和S誰(shuí)比較大,跟大的換位置
跟S換之后,發(fā)現(xiàn)依然比子節(jié)點(diǎn)要小,還是要下浮,最后
下沉的代碼如下:
public void sink(int k) { //判斷是否超過(guò)數(shù)組最大長(zhǎng)度 while (2 * k < N) { //找到子節(jié)點(diǎn) int j = 2 * k; //兩個(gè)子節(jié)點(diǎn)進(jìn)行比較,選大的 if (j < N && less(j, j + 1)) j++; //沒(méi)有比子節(jié)點(diǎn)小,就跳出循環(huán) if (!less(k, j)) break; exch(k, j); k = j; } }上浮和下沉的應(yīng)用(敲黑板,重點(diǎn))
向數(shù)組插入value會(huì)用到上浮
每次向隊(duì)尾插入一個(gè)value時(shí),都要檢查是否違反最大堆的平衡性。
刪除根節(jié)點(diǎn)時(shí),會(huì)用到下沉
每次想刪除根節(jié)點(diǎn),第一步是要將跟節(jié)點(diǎn)與最后一個(gè)節(jié)點(diǎn)互換位置后,將其刪除,此時(shí)最后一個(gè)節(jié)點(diǎn)作為根節(jié)點(diǎn),一定會(huì)比子節(jié)點(diǎn)要小,違反平衡性,那就下浮
堆排序很簡(jiǎn)單,最大堆為例,根節(jié)點(diǎn)是最大的節(jié)點(diǎn),每次將根節(jié)點(diǎn)和最后一個(gè)子節(jié)點(diǎn)對(duì)調(diào)位置,此時(shí)數(shù)組的最后一位即為最大,待其最大堆再次平衡時(shí),再將根節(jié)點(diǎn)和最后一個(gè)子節(jié)點(diǎn)對(duì)調(diào),即為排序。例如:
數(shù)組元素為{a,b,c,d,e},假設(shè)二叉堆已經(jīng)平衡,a為根節(jié)點(diǎn),也就是最大的節(jié)點(diǎn),將a和e對(duì)調(diào), {e,b,c,d,a},數(shù)組的長(zhǎng)度此時(shí)應(yīng)該減一,將數(shù)組的前四位進(jìn)行二叉堆的平衡,e肯定要下沉到相應(yīng)位置,然后再將根節(jié)點(diǎn)和長(zhǎng)度減一后的最后一個(gè)節(jié)點(diǎn)對(duì)調(diào)位置。
這是我對(duì)二叉堆的理解,如有不對(duì),歡迎指正,我會(huì)立即修改,謝謝。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/69648.html
摘要:模型優(yōu)先隊(duì)列是允許至少下列兩種操作的數(shù)據(jù)結(jié)構(gòu)以及找出返回并刪除優(yōu)先隊(duì)列中最小的元素。左式堆也是二叉樹(shù),左式堆和二叉堆的唯一區(qū)別是左式堆不是理想平衡,而實(shí)際上趨向于非常不平衡。事實(shí)上,沿左式堆的右路徑是該堆中的最短路徑。 6.1 模型 優(yōu)先隊(duì)列是允許至少下列兩種操作的數(shù)據(jù)結(jié)構(gòu):insert 以及 deleteMin(找出、返回并刪除優(yōu)先隊(duì)列中最小的元素)。 insert 操作等價(jià)于 en...
摘要:構(gòu)建二叉樹(shù)構(gòu)建二叉樹(shù),就是把一個(gè)無(wú)序的完全二叉樹(shù)調(diào)整為二叉堆,本質(zhì)上就是讓所有非葉子節(jié)點(diǎn)一次下沉上浮構(gòu)建最大堆節(jié)點(diǎn)大的上浮,小的下沉構(gòu)建最小堆節(jié)點(diǎn)小的上浮,大的下沉文章什么是二叉堆 什么是二叉堆 二叉堆的本質(zhì)是一種完全二叉樹(shù),它分為兩種類型:最大堆和最小堆 最大堆任何一個(gè)父節(jié)點(diǎn)的值,都大于等于它左右孩子的值,最小堆正好與之相反 showImg(https://segmentfault....
摘要:二叉堆數(shù)據(jù)結(jié)構(gòu)是一種特殊的二叉樹(shù),他能高效快速的找出最大值和最小值,常應(yīng)用于優(yōu)先隊(duì)列和著名的堆排序算法中。 二叉堆數(shù)據(jù)結(jié)構(gòu)是一種特殊的二叉樹(shù),他能高效、快速的找出最大值和最小值,常應(yīng)用于優(yōu)先隊(duì)列和著名的堆排序算法中。 二叉堆 二叉堆有以下兩個(gè)特性: 是一顆完全二叉樹(shù),表示數(shù)的每一層都有左側(cè)和右側(cè)子節(jié)點(diǎn)(除最后一層的葉節(jié)點(diǎn)),并且最后一層的葉節(jié)點(diǎn)盡可能是左側(cè)子節(jié)點(diǎn) 二叉堆不是最小堆就是...
摘要:二叉堆的有趣之處在于,其邏輯結(jié)構(gòu)上像二叉樹(shù),卻是用非嵌套的列表來(lái)實(shí)現(xiàn)。二叉堆結(jié)構(gòu)性質(zhì)為了更好地實(shí)現(xiàn)堆,我們采用二叉樹(shù)。圖完全二叉樹(shù)有意思的是我們用單個(gè)列表就能實(shí)現(xiàn)完全樹(shù)。下列所示的代碼是完全二叉堆的實(shí)現(xiàn)。 優(yōu)先隊(duì)列的二叉堆實(shí)現(xiàn) 在前面的章節(jié)里我們學(xué)習(xí)了先進(jìn)先出(FIFO)的數(shù)據(jù)結(jié)構(gòu):隊(duì)列(Queue)。隊(duì)列有一種變體叫做優(yōu)先隊(duì)列(Priority Queue)。優(yōu)先隊(duì)列的出隊(duì)(Dequ...
閱讀 1625·2023-04-26 02:43
閱讀 3046·2021-11-11 16:54
閱讀 1363·2021-09-23 11:54
閱讀 1183·2021-09-23 11:22
閱讀 2374·2021-08-23 09:45
閱讀 856·2019-08-30 15:54
閱讀 3107·2019-08-30 15:53
閱讀 3198·2019-08-30 15:53