算法導論讀書筆記(10)

http://www.cnblogs.com/sungoshawk/p/3649004.html

算法導論讀書筆記(10)

棧和隊列

棧和隊列都是動態集合。棧實現了一種 先進先出 的策略。類似地,隊列實現了一種 後進先出 的策略。

作用於棧上的 INSERT 操作稱爲 壓入 ( PUSH ),而無參的 DELETE 操作常稱爲 彈出 ( POP )。可以使用一個數組 S [ 1 .. n ]來實現一個至多有 n 個元素的棧。如下圖所示,數組 S 有個屬性 S.top ,它指向最近插入的元素。

STACK-EMPTY(S)
1 if S.top == 0
2     return TRUE
3 else
4     return FALSE
PUSH(S, x)
1 S.top = S.top + 1
2 S[S.top] = x
POP(S)
1 if STACK-EMPTY(S)
2     error "underflow"
3 else
4     S.top = S.top - 1
5 return S[S.top + 1]

隊列

我們把作用於隊列上的 INSERT 操作稱爲 入隊 ( ENQUEUE ),把作用於隊列上的 DELETE 操作稱爲 出隊 ( DEQUEUE )。隊列有  和  。當一個元素入隊時,將排在隊尾,而出隊的元素總是隊首元素。下圖說明了用一個數組 Q [ 1 .. n ]來實現一個至多含 n - 1 個元素的隊列的方法。隊列具有屬性 Q.head ,它指向隊列的頭,另一個屬性爲 Q.tail ,它指向新元素將會被插入的地方。

ENQUEUE(Q, x)
1 Q[Q.tail] = x
2 if Q.tail == Q.length
3     Q.tail = 1
4 else
5     Q.tail = Q.tail + 1
DEQUEUE(Q)
1 x = Q[Q.head]
2 if Q.head == Q.length
3     Q.head = 1
4 else
5     Q.head = Q.head + 1
6 return x

鏈表

在 鏈表 中,各對象按線性順序排序。其順序由各對象中的指針決定。本節介紹的是無序的雙鏈表。 雙鏈表 的每一個元素都是一個對象,每個對象包含一個關鍵字域和兩個指針域: next 和 prev 。對鏈表中的某個元素 x , x.next 指向鏈表中 x 的後繼元素,而 x.prev 則指向鏈表中 x 的前驅元素。下面給出的是鏈表的基本操作。

LIST-SEARCH(L, k)
1 x = L.head
2 while x != NIL and x.key != k
3     x = x.next
4 return x
LIST-INSERT(L, x)
1 x.next = L.head
2 if L.head != NIL
3     L.head.prev = x
4 L.head = x
5 x.prev = NIL
LIST-DELETE(L, x)
1 if x.prev != NIL
2     x.prev.next = x.next
3 else
4     L.head = x.next
5 if x.next != NIL
6     x.next.prev = x.prev

有根樹的表示

用鏈表表示有根樹

二叉樹

如下圖所示,用域 p , left , right 來存放指向二叉樹 T 中的父親,左兒子和右兒子的指針。如果 x.p = NIL ,則 x 爲根。如果結點 x 無左兒子,則 x.left =NIL ,對右兒子也類似。整個樹 T 的根由屬性 T.root 指向。如果 T.root = NIL ,則樹爲空。

分支數無限的有根樹

可以用二叉樹很方便地表示具有任意子女數的樹。該方法的優點是對任意含 n 個結點的有根樹僅用 O ( n )空間。這種 左孩子 , 右兄弟 的表示如下圖所示。每個結點都包含一個父親指針 p , T.root 指向樹 T 的根。每個結點 x 不再包含指向每個孩子結點的指針,而僅包含兩個指針:

  1. x.left-child 指向結點 x 的最左孩子。
  2. x.right-sibling 指向結點 x 緊右邊的兄弟。

如果 x 沒有孩子,則 x.left-child = NIL ;如果 x 是其父結點的最右孩子,則 x.right-sibling = NIL 。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章