最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

數(shù)據(jù)結(jié)構(gòu)與算法_線段樹

2023-08-05 21:53 作者:昵昵醬紫  | 我要投稿

線段樹(segment tree)是一種二叉搜索樹,也是平衡二叉樹,它的每一個(gè)結(jié)點(diǎn)對(duì)應(yīng)一個(gè)區(qū)間?[L,R] ,葉子結(jié)點(diǎn)對(duì)應(yīng)的區(qū)間只有一個(gè)結(jié)點(diǎn)(L = R)。每一個(gè)非葉子結(jié)點(diǎn) [L , R] ,其左孩子區(qū)間為 [L, (L+R)/2] ,右孩子區(qū)間為 [ (L+R)/2+1, R] 。

????因?yàn)榫€段樹是平衡二叉樹,所以樹高為 log(n),樹上的操作大多和樹高有關(guān)。線段樹主要用于更新和查詢,一般至少有一個(gè)是區(qū)間更新或查詢。更新和查新的種類變化多端,靈活運(yùn)用線段樹可以解決多種問(wèn)題。

????例如,區(qū)間最值查詢問(wèn)題(Rang Minimum/Maximum Query, RMQ),該問(wèn)題有兩種操作:(1) 點(diǎn)更新:修改一個(gè)元素的值;(2)區(qū)間查詢:查詢一個(gè)區(qū)間的最值。

1. 線段樹的實(shí)現(xiàn)

以區(qū)間最值查詢問(wèn)題為例,講述線段的實(shí)現(xiàn)過(guò)程。

(1)存儲(chǔ)方式

????因?yàn)橐樵儏^(qū)間最大值(最大值或最小值),因此每個(gè)結(jié)點(diǎn)包含三個(gè)域:l, r, mx, 其中 l?和 r 分別表示區(qū)間的左右端點(diǎn), mx表示區(qū)間 [ l, r] 的最值。本題以最大值為例。例如,有 10個(gè)元素 a[ 1 ... 10] = {5, 3, 7, 2, 12, 1, 6, 4, 8, 15} ,線段樹如圖所示。

????由于線段樹除了最后一層外,其他層構(gòu)成一個(gè)滿二叉樹,因此可以采用順序存儲(chǔ)方式,用一個(gè)數(shù)組 tree[ ] 存儲(chǔ)結(jié)點(diǎn)。如果一個(gè)結(jié)點(diǎn)的存儲(chǔ)下標(biāo)為 k, 則左孩子的下標(biāo)為 2k, 右孩子的下標(biāo)為 2k+1 。 如圖所示:

????線段樹根節(jié)點(diǎn)的存儲(chǔ)下標(biāo)為 1,其左右孩子存儲(chǔ)下標(biāo)分別為 2,3 。。。

(2) 創(chuàng)建線段樹

????可以采用遞歸的方法創(chuàng)建線段樹,其創(chuàng)建過(guò)程如下:

????1) 如果是葉子結(jié)點(diǎn) (r = l), 則結(jié)點(diǎn)的最值就是對(duì)應(yīng)位置的元素值;

????2) 如果是非葉子結(jié)點(diǎn),遞歸創(chuàng)建左子樹 和右子樹;

????3)結(jié)點(diǎn)的區(qū)間最值等于該結(jié)點(diǎn)左右子樹最值的最大值;

????代碼實(shí)現(xiàn):

(3) 點(diǎn)更新

????點(diǎn)更新是指修改一個(gè)元素的值,例如將 a[i] 修改為 v, 仍然采用遞歸的方法進(jìn)行點(diǎn)更新,其過(guò)程如下:

????1)如果是第 i 個(gè)元素所在的葉子結(jié)點(diǎn)(r = l 且 l = i),則修改結(jié)點(diǎn)的最值為 v;

????2) 如果是非葉子結(jié)點(diǎn),則判斷在左子樹中更新還是在右子樹中更新;

????3) 返回時(shí)更新結(jié)點(diǎn)的最值;

????代碼實(shí)現(xiàn):

(4)區(qū)間查詢

????區(qū)間查詢是指查詢一個(gè)個(gè)區(qū)間的最值。仍然采用遞歸的方法進(jìn)行區(qū)間查詢,其過(guò)程如下:

????1)如果結(jié)點(diǎn)的區(qū)間被查詢區(qū)間 [l, r] 覆蓋,則返回該結(jié)點(diǎn)的最值;

????2)判斷在左子樹查詢,右子樹查詢;

????3)返回最值;

(5)區(qū)間更新

????對(duì) [l,r] 進(jìn)行區(qū)間更新:

????1) 如果結(jié)點(diǎn)的區(qū)間被查詢區(qū)間 [l,r] 覆蓋,僅對(duì)該結(jié)點(diǎn)進(jìn)行更新,并作懶標(biāo)記,表示該結(jié)點(diǎn)被更新過(guò),對(duì)該結(jié)點(diǎn)的子結(jié)點(diǎn)不再進(jìn)行更新;

????2)判斷在左子樹查詢,右子樹查詢。查詢過(guò)程中,若當(dāng)前結(jié)點(diǎn)帶有懶標(biāo)記,懶標(biāo)記下傳給子結(jié)點(diǎn) (當(dāng)前結(jié)點(diǎn)懶標(biāo)記清除,子結(jié)點(diǎn)更新并做懶標(biāo)記),繼續(xù)查詢;

????3)更新最值。

????例如,在[1 , 10] 的線段樹中修改 [4,8] 區(qū)間的值為 20.

代碼實(shí)現(xiàn):


2. 線段樹的性能分析:

????線段樹采用了分治算法策略,其點(diǎn)更新,區(qū)間更新,區(qū)間查詢均可以在O(log n) 時(shí)間內(nèi)完成。樹狀數(shù)組和線段樹都用于頻繁的修改和查詢問(wèn)題,樹狀數(shù)組可以實(shí)現(xiàn)點(diǎn)更新,區(qū)間查詢,而線段樹還可以實(shí)現(xiàn)區(qū)間更新,區(qū)間查詢。線段樹的用途更廣,更靈活,樹狀數(shù)組比線段樹節(jié)省空間,代碼簡(jiǎn)單易懂,但是線段樹更靈活,凡是能用樹狀數(shù)組的問(wèn)題一定能用線段樹。

數(shù)據(jù)結(jié)構(gòu)與算法_線段樹的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
巴林左旗| 乃东县| 丹阳市| 远安县| 洛阳市| 藁城市| 五大连池市| 曲周县| 分宜县| 北宁市| 鲜城| 农安县| 淳安县| 阿巴嘎旗| 寿阳县| 儋州市| 新晃| 博白县| 蒙山县| 南阳市| 自贡市| 武定县| 穆棱市| 宜兴市| 莆田市| 天门市| 临江市| 潢川县| 宁河县| 海晏县| 迭部县| 成安县| 元阳县| 太谷县| 云林县| 廊坊市| 抚顺县| 乐业县| 毕节市| 通化市| 五家渠市|