日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

算法导论第十二章:二叉查找树

發(fā)布時(shí)間:2025/4/14 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法导论第十二章:二叉查找树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

查找樹(shù)是一種數(shù)據(jù)結(jié)構(gòu),它支持多種動(dòng)態(tài)集合操作,包括search, minimum, maximum, predecessor, successor, insert以及delete。他既可以用作字典,也可以用作優(yōu)先隊(duì)列。

二叉查找樹(shù)上基本操作的執(zhí)行時(shí)間和樹(shù)的高度成正比。對(duì)一棵n個(gè)結(jié)點(diǎn)的完全二叉樹(shù)來(lái)說(shuō),這些操作的最壞情況運(yùn)行時(shí)間為Θ(lgn)。但是如果樹(shù)是含有那個(gè)結(jié)點(diǎn)的線(xiàn)性鏈,則這些操作的最壞運(yùn)行時(shí)間是Θ(n)。本章可以看到一棵隨機(jī)構(gòu)造的二叉查找樹(shù)的期望高度為O(lgn)

實(shí)際中,并不能總是保證二叉查找樹(shù)是隨機(jī)構(gòu)造的,但有些二叉查找樹(shù)的變形能保證各種基本操作的最壞情況性能。第十三章介紹的紅黑樹(shù),其高度為O(lgn)。第十八章介紹B樹(shù),這種結(jié)構(gòu)對(duì)維護(hù)隨機(jī)訪(fǎng)問(wèn)的二級(jí)存儲(chǔ)器上的數(shù)據(jù)庫(kù)特別有效。

?

二叉查找樹(shù)

? 二叉查找樹(shù)是按二叉樹(shù)結(jié)構(gòu)來(lái)組織的,每個(gè)結(jié)點(diǎn)除了key域和衛(wèi)星數(shù)據(jù)外,還包含leftrightp。結(jié)點(diǎn)的存儲(chǔ)方案滿(mǎn)足以下性質(zhì):如果結(jié)點(diǎn)y是結(jié)點(diǎn)x左子樹(shù)種的一個(gè)結(jié)點(diǎn),則key[y]<=key[x]。如果yx右子樹(shù)中的一個(gè)結(jié)點(diǎn),則key[x]<=key[y]

?

對(duì)二叉查找樹(shù)進(jìn)行中序遍歷可以有序輸出所有的結(jié)點(diǎn)關(guān)鍵字。

?

練習(xí):

12.1.3給出二叉樹(shù)的一個(gè)非遞歸的中序遍歷算法。

1)可以用一個(gè)棧數(shù)據(jù)結(jié)構(gòu)來(lái)模擬遞歸過(guò)程中的棧變化過(guò)程,從而完成非遞歸形式的遍歷算法;

2)也可以不借助棧數(shù)據(jù)結(jié)構(gòu),中序遍歷的過(guò)程中是由從根到葉、從父到子的down過(guò)和從子到父的up過(guò)程組成的。在非遞歸的情況下,在處理某個(gè)節(jié)點(diǎn)x時(shí),關(guān)鍵是要分清下一步是要down還是up。其實(shí)這可以由上一個(gè)結(jié)點(diǎn)位置來(lái)判斷,如果上一個(gè)結(jié)點(diǎn)是x的父節(jié)點(diǎn)且x是它的左兒子,則應(yīng)該往左down,如果x是它的右兒子,則應(yīng)該up。如果上一結(jié)點(diǎn)是x的左兒子,則應(yīng)該往右down,如果是x的右兒子,則應(yīng)該up

OPTYPE {down, up}

INORDER_WITHOUTSTACKT

1???????? Node x = root[T]

2???????? Node last_node = nil

3???????? OPTYPE last_op = down

4???????? while (!over)

5???????? ??switch (last_op)

6???????? ????Case down:???????

7???????? ???????If (left[x]) last_node=x, last_op=down, x=left[x]

8???????? ???????Else output(x);

9???????? ???????????if (right[x]) last_node=x, last_op=down, x=right[x]

10???? ???????????Else if (x.p) last_node=x,last_op=up,x=x.p

11???? ???????????????Else over=true

12???? ????Case up:

13???? ???????If (last_node = left[x]) output(x)

14???? ??????????????????????????If (right[x]) last_node=x, last_op=down, x=right[x]

15???? ????????????????????????Else if (x.p) last_node=x,last_op=up,x=x.p

16???? ????????????????????????????Else over=true

17???? ?????Else if (x.p) last_node=x,last_op=up,x=x.p

18???? ????????????????????????????Else over=true?

?

查詢(xún)二叉查找樹(shù)

查找關(guān)鍵字k

從樹(shù)根開(kāi)始比較key[x]k,如果key[x]=k停止,如果key[x]>k則往左子樹(shù)查找,否則往右子樹(shù)查找,如此循環(huán)。

?

最大關(guān)鍵字元素和最小關(guān)鍵字元素:

最大關(guān)鍵字就是樹(shù)的最右結(jié)點(diǎn):沿樹(shù)根往右子節(jié)點(diǎn)移動(dòng),直到NIL。

最小關(guān)鍵字元素就是樹(shù)的最左結(jié)點(diǎn):沿樹(shù)根往左子結(jié)點(diǎn)移動(dòng),直到NIL。

?

前驅(qū)和后繼:

某個(gè)節(jié)點(diǎn)x的前驅(qū):如果x有左子,那么前驅(qū)是左子樹(shù)的最大關(guān)鍵字;否則從下往上查看x的祖先結(jié)點(diǎn),直到某個(gè)節(jié)點(diǎn)y滿(mǎn)足性質(zhì):x出現(xiàn)在y的右子樹(shù)種。如果y存在,則y就是x的前驅(qū),否則x沒(méi)有前驅(qū)。

某個(gè)節(jié)點(diǎn)x的后繼:如果x有右子,則x的后繼是右子樹(shù)的最小關(guān)鍵字;否則從下往上查看x的祖先結(jié)點(diǎn),直到某個(gè)結(jié)點(diǎn)y滿(mǎn)足性質(zhì):x出現(xiàn)在y的左字?jǐn)?shù)中,如果y存在,則yx的后繼,否則x沒(méi)有后繼。

?

查找前驅(qū)和后繼的最壞運(yùn)行時(shí)間為lgn

但對(duì)x查找其后繼(前驅(qū))的k個(gè)結(jié)點(diǎn)的運(yùn)行時(shí)間為lgn+k,以前驅(qū)為例,證明如下:

假設(shè)x的左子樹(shù)有k1個(gè)結(jié)點(diǎn),如果k<k1,則k1時(shí)間內(nèi)就可以完成,假設(shè)k1<k,遍歷這k1個(gè)結(jié)點(diǎn)需要k1時(shí)間,找到下一個(gè)前驅(qū)需要往根方向移動(dòng),不妨設(shè)移動(dòng)的距離為h1。如此往復(fù)。假設(shè)期間產(chǎn)生了 k1,k2,k3..h1,h2…這些數(shù)據(jù)??芍?/span> k1+k2+k3…<=kh1+h2+…<=樹(shù)的高度。所以運(yùn)行時(shí)間k1+k2+k3+…+h1+h2+…<=lgn+k。

實(shí)際上,如果對(duì)樹(shù)的最小結(jié)點(diǎn)調(diào)用n-1次后繼操作,等同于中序遍歷二叉查找樹(shù)。

?

插入刪除結(jié)點(diǎn)

插入一個(gè)結(jié)點(diǎn)與查找一個(gè)關(guān)鍵字的過(guò)程是基本一致的。當(dāng)查找過(guò)程到達(dá)nil時(shí),這個(gè)位置就是插入的位置。

刪除的過(guò)程要稍微復(fù)雜一點(diǎn):

(1)?????? 如果結(jié)點(diǎn)沒(méi)有子節(jié)點(diǎn),則直接刪除。

(2)?????? 如果結(jié)點(diǎn)只有左子樹(shù)或右子樹(shù),則刪除該節(jié)點(diǎn),然后用該子樹(shù)的根節(jié)點(diǎn)來(lái)取代該節(jié)點(diǎn)的位置。

(3)?????? 如果該節(jié)點(diǎn)有左右子樹(shù),則將該節(jié)點(diǎn)的數(shù)據(jù)與其前驅(qū)或后繼結(jié)點(diǎn)的數(shù)據(jù)進(jìn)行交換,再刪除該前驅(qū)或后繼結(jié)點(diǎn)

?

隨機(jī)構(gòu)造的二叉查找樹(shù)

二叉查找樹(shù)的操作性能依賴(lài)于樹(shù)的高度,為了避免壞的關(guān)鍵字順序造成樹(shù)的高度過(guò)高,可以采用隨機(jī)化的手段來(lái)構(gòu)造樹(shù)。可以證明,隨機(jī)構(gòu)造的二叉查找樹(shù)的期望高度為O(lgn)。

先定義三個(gè)隨機(jī)變量:

Xnn個(gè)結(jié)點(diǎn)的二叉查找樹(shù)的高度;

Yn:指數(shù)高度Yn=2XnYn = 2*max(Yi-1,Yn-i)。

Rn:根節(jié)點(diǎn)的在關(guān)鍵字中的統(tǒng)計(jì)順序。

Zn,i:定義指示器隨機(jī)變量Zn,i=I{Rn=i}; E[Zn,i] = 1/n。

推理過(guò)程如下:

????????????????????????????????????????????????????????????????????

利用恒等式:,用數(shù)學(xué)歸納得出,再利用jensen不等式:,可得E[Xn] = O(lgn)。

?

?

?

?

隨機(jī)構(gòu)造二叉查找樹(shù)與隨機(jī)化快速排序比較

在構(gòu)造二叉樹(shù)的時(shí)候,當(dāng)選定某個(gè)關(guān)鍵字稱(chēng)為根節(jié)點(diǎn)之后,那么比這個(gè)關(guān)鍵字大的關(guān)鍵字都將出現(xiàn)在該節(jié)點(diǎn)的右字?jǐn)?shù),小的關(guān)鍵字都將出現(xiàn)在左子樹(shù)。這個(gè)過(guò)程與快速排序選定中軸節(jié)點(diǎn)的過(guò)程及其相似。進(jìn)一步,所有的結(jié)點(diǎn)都將與根節(jié)點(diǎn)進(jìn)行比較,但左子樹(shù)中的結(jié)點(diǎn)不會(huì)與右子樹(shù)的結(jié)點(diǎn)比較,反之亦然??梢钥闯鰳?gòu)造二叉查找樹(shù)的過(guò)程與快速排序的過(guò)程驚人地相似,實(shí)際上如果將選定根節(jié)點(diǎn)和選定中軸結(jié)點(diǎn)相對(duì)應(yīng),那么兩者整個(gè)過(guò)程中所進(jìn)行的元素比較是完全相同的,只是順序不一致而已。

?

可以分析二叉查找樹(shù)的平均結(jié)點(diǎn)深度。每個(gè)結(jié)點(diǎn)的深度等于其在插入樹(shù)的過(guò)程中的比較次數(shù),所有的比較次數(shù)之和平均為nlgn,因此平均的結(jié)點(diǎn)深度為lgn。

?

思考題

基數(shù)樹(shù):

基數(shù)樹(shù)數(shù)據(jù)結(jié)構(gòu),用來(lái)存儲(chǔ)0,1位串,位置串并沒(méi)有存儲(chǔ)在節(jié)點(diǎn)中,一個(gè)結(jié)點(diǎn)只要標(biāo)明從根到該節(jié)點(diǎn)的路徑是否構(gòu)成一個(gè)有效位串。當(dāng)查找某關(guān)鍵字a=a0a1…ap,時(shí),在深度為i的一個(gè)結(jié)點(diǎn)處,如果ai=0,則向左轉(zhuǎn),如果ai=1則向右轉(zhuǎn)。下圖的基數(shù)樹(shù)存儲(chǔ)了位串0,001,10 1001011.白色結(jié)點(diǎn)為有效位串的終結(jié)結(jié)點(diǎn)。

設(shè)S為一組不同的二進(jìn)制構(gòu)成的集合,各串的長(zhǎng)度之和為n。說(shuō)明如何利用基數(shù)樹(shù),在Θ(n)時(shí)間內(nèi)將S按字典順序排序。

?

分析:構(gòu)造基數(shù)樹(shù)的過(guò)程很顯然,假設(shè)一個(gè)位串的長(zhǎng)度為k,則只需要時(shí)間k就可以將串插入基數(shù)樹(shù)中。然后進(jìn)行中序遍歷就可以,按序輸出。

如果將基數(shù)樹(shù)擴(kuò)展,是否可以用來(lái)存儲(chǔ)一般的字符串,并加快查找過(guò)程?

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/longhuihu/archive/2011/02/26/10423370.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的算法导论第十二章:二叉查找树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。