两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

一、簡介

手指樹(Finger Tree)是一種純函數(shù)式數(shù)據(jù)結(jié)構(gòu),由 Ralf Hinze 和 Ross Paterson 提出。


二、為什么需要手指樹?

在函數(shù)式編程中,列表是十分常見的數(shù)據(jù)類型。對于基于序列的操作,包括在兩端添加和刪除元素(雙端隊列操作),在任意節(jié)點插入、連接、刪除,查找某個滿足要求的元素,將序列拆分為子序列,幾乎所有的函數(shù)型語言都支持。但是對于高效的更多操作,這些語言很難做到。即使有相對應(yīng)的實現(xiàn),通常也都非常復(fù)雜,實際很難使用。

而指狀樹提供了一種純函數(shù)式的序列數(shù)據(jù)結(jié)構(gòu),它可以在均攤常量時間(amortized constant time)內(nèi)完成訪問,添加到序列的前端和末尾等操作,以及在對數(shù)時間(logarithmic time)內(nèi)完成串聯(lián)和隨機訪問。除了良好的漸近運行時邊界外,手指樹還非常靈活:當(dāng)與元素上的幺半群標(biāo)記(monoidal tag)結(jié)合時,指狀樹可用于實現(xiàn)高效的隨機訪問序列、有序序列、間隔樹和優(yōu)先級隊列。


三、基本結(jié)構(gòu)

手指樹在樹的“手指”(葉子)的地方存儲數(shù)據(jù),訪問時間為分?jǐn)偝A俊J种甘且粋€可以訪問部分?jǐn)?shù)據(jù)結(jié)構(gòu)的點。在命令式語言(imperative language)中,這被稱做指針。在手指樹中,“手指”是指向序列末端或葉節(jié)點的結(jié)構(gòu)。手指樹還在每個內(nèi)部節(jié)點中存儲對其后代應(yīng)用一些關(guān)聯(lián)操作的結(jié)果。存儲在內(nèi)部節(jié)點中的數(shù)據(jù)可用于提供除樹類數(shù)據(jù)結(jié)構(gòu)之外的功能。

1. 手指樹的深度由下到上計算。

2. 手指樹的第一級,即樹的葉節(jié)點,僅包含值,深度為 。第二級為深度 。第三級為深度 ,依此類推。

3. 離根越近,節(jié)點指向的原始樹(在它是手指樹之前的樹)的子樹越深。這樣,沿著樹向下工作就是從葉子到樹的根,這與典型的樹數(shù)據(jù)結(jié)構(gòu)相反。為了獲得這種的結(jié)構(gòu),我們必須確保原始樹具有統(tǒng)一的深度。在聲明節(jié)點對象時,必須通過子節(jié)點的類型進行參數(shù)化。深度為  及以上的脊椎上的節(jié)點指向樹,通過這種參數(shù)化,它們可以由嵌套節(jié)點表示。


將一棵樹變成手指樹

注釋:2-3樹是一種樹狀數(shù)據(jù)結(jié)構(gòu),其中每個帶有子節(jié)點(內(nèi)部節(jié)點)的節(jié)點具有兩個子節(jié)點( 節(jié)點)和一個數(shù)據(jù)元素或三個子節(jié)點( 節(jié)點)和兩個數(shù)據(jù)元素。2-3樹是3階B樹。樹外部的節(jié)點(葉節(jié)點)沒有子節(jié)點和一兩個數(shù)據(jù)元素。

我們將從平衡 2-3 樹開始這個過程。為了使手指樹正常工作,所有的葉節(jié)點需要是水平的。如下圖所示

將一棵樹變成手指樹

手指是“一種結(jié)構(gòu),可以有效地訪問靠近特定位置的樹的節(jié)點。”要制作手指樹,我們需要將手指放在樹的左右兩端,取樹的最左邊和最右邊的內(nèi)部節(jié)點并將它們拉起來,使樹的其余部分懸在它們之間,這為我們提供了對序列末尾的均攤常量訪問時間。

手指樹

這種新的數(shù)據(jù)結(jié)構(gòu)被稱為手指樹。手指樹由沿其樹脊(棕色線)分布的幾層(下方藍色框)組成:

手指樹

data FingerTree a = Empty
                  | Single a
                  | Deep (Digit a) (FingerTree (Node a)) (Digit a)

data Digit a = One a | Two a a | Three a a a | Four a a a a
data Node a = Node2 a a | Node3 a a a

示例中的數(shù)字是帶有字母的節(jié)點。每個列表由樹脊上每個節(jié)點的前綴或后綴劃分。在轉(zhuǎn)換后的2-3樹中,頂層的數(shù)字列表似乎可以有兩個或三個長度,而較低級別的長度只有一或兩個。為了使手指樹的某些應(yīng)用程序能夠如此高效地運行,手指樹允許在每個級別上有1到4個子樹。手指樹的數(shù)字可以轉(zhuǎn)換成一個列表,如:

type Digit a = One a | Two a a | Three a a a | Four a a a a

頂層具有類型 a 的元素,下一層具有類型節(jié)點 a 的元素,因為樹脊和葉子之間的節(jié)點,這通常意味著樹的第 n 層具有元素類型為元素類型,或 2-3 個深度為 n 的樹。這意味著 n 個元素的序列由深度為 Θ(log n) 的樹表示。距離最近端 d 的元素存儲在樹中 Θ(log d) 深度處。


雙向隊列操作

指狀樹也可以制作高效的雙向隊列。無論結(jié)構(gòu)是否持久,所有操作都需要 Θ(1) 時間。它可以被看作是的隱式雙端隊列的擴展:

(1)用 2-3 個節(jié)點替換對提供了足夠的靈活性來支持有效的串聯(lián)。(為了保持恒定時間的雙端隊列操作,必須將 Digit 擴展為四。)

(2)用幺半群(monoid)注釋內(nèi)部節(jié)點允許有效的分裂。

data ImplicitDeque a = Empty
                     | Single a
                     | Deep (Digit a) (ImplicitDeque (a, a)) (Digit a)

data Digit a = One a | Two a a | Three a a a


四、時間復(fù)雜度

手指樹提供了對樹的“手指”(葉子)的分?jǐn)偝A繒r間訪問,這是存儲數(shù)據(jù)的地方,以及在較小部分的大小中連接和拆分對數(shù)時間。它還在每個內(nèi)部節(jié)點中存儲對其后代應(yīng)用一些關(guān)聯(lián)操作的結(jié)果。存儲在內(nèi)部節(jié)點中的“摘要”數(shù)據(jù)可用于提供除樹之外的數(shù)據(jù)結(jié)構(gòu)的功能。

操作手指樹注釋 2-3 樹 (annotated 2-3 tree)列表(list)向量(vector
const,snocO(1)O(logn)O(1)/O(n)O(n)
viewl,viewrO(1)O(logn)O(1)/O(n)O(1)
measure/lengthO(1)O(1)O(n)O(1)
appendO(log min(l1, l2))O(logn)O(n)O(m+n)
splitO(log min(n, l-n))O(logn)O(n)O(1)
replicateO(log n)O(logn)O(n)O(n)
fromList,toList,reverseO(l)/O(l)/O(l)O(l)O(1)/O(1)/O(n)O(n)
indexO(log min(n, l-n))O(logn)O(n)O(1)


五、應(yīng)用

指狀樹可用于建造其他樹。例如,優(yōu)先級隊列可以通過樹中子節(jié)點的最小優(yōu)先級標(biāo)記內(nèi)部節(jié)點來實現(xiàn),或者索引列表/數(shù)組可以通過節(jié)點的子節(jié)點中葉子的計數(shù)來標(biāo)記節(jié)點來實現(xiàn)。其他應(yīng)用包括隨機訪問序列(如下所述)、有序序列和區(qū)間樹。

手指樹可以提供平均O(1)的推、反轉(zhuǎn)、彈出, O(logn)追加和拆分;并且可以適應(yīng)索引或排序序列。和所有函數(shù)式數(shù)據(jù)結(jié)構(gòu)一樣,它本質(zhì)上是持久的;也就是說,始終保留舊版本的樹。

對于代碼實現(xiàn),Haskell核心庫中的有限序列 Seq 的實現(xiàn)使用了2-3手指樹(Data.Sequence),OCaml 中 BatFingerTree 模塊的實現(xiàn) 也使用了通用手指樹數(shù)據(jù)結(jié)構(gòu)。手指樹可以使用或不使用惰性求值來實現(xiàn),但惰性允許更簡單的實現(xiàn)。

點贊(0)

C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點擊了解:

一點編程也不會寫的:零基礎(chǔ)C語言學(xué)練課程

解決困擾你多年的C語言疑難雜癥特性的C語言進階課程

從零到寫出一個爬蟲的Python編程課程

只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程

信息學(xué)奧賽或C++選手的 必學(xué)C++課程

藍橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程

手把手講解近五年真題的藍橋杯輔導(dǎo)課程

Dotcpp在線編譯      (登錄可減少運行等待時間)