搜索樹數據結構支持多種動態集合操做,包括SEARCH、MINIMUM、MAXIMUM、PREDECESSOR、SUCCESSOR、INSRT和DELETE操做等。基本的搜索樹就是一棵二叉搜索樹。
12.1 什麼是二叉搜索樹
1. 二叉搜索樹的性質:
設x是二叉搜索樹中的一個結點。若是y是x左子樹中的一個結點,那麼y.key<=x.key。若是y是x右子樹中的一個結點,那麼y.key>=x.key。
三種遍歷時間複雜度是O(n),這是顯然的。
12.1-3算法
1 void Inorder_Tree_Walk_Nonrecursive_1(Node_t *x) { 2 stack<Node_t *> S; 3 bool mid = false; 4 5 printf("Using stack to implement Inorder_Tree_Walk:\n"); 6 S.push(x); 7 while (!S.empty()) { 8 if (x->l == NULL || mid) { 9 printf("%d ", x->key); 10 S.pop(); 11 if (x->r == NULL) { 12 if (S.empty()) 13 break; 14 x = S.top(); 15 mid = true; 16 } else { 17 x = x->r; 18 S.push(x); 19 mid = false; 20 } 21 } else { 22 x = x->l; 23 S.push(x); 24 } 25 } 26 printf("\n"); 27 } 28 void Inorder_Tree_Walk_Nonrecursive_2(Node_t *x) { 29 printf("Using nonstack to implement Inorder_Tree_Walk:\n"); 30 Node_t *p = x->p, *y = NULL; 31 bool ret = false, retr = false; 32 33 while (!retr || y!=p) { 34 if (x->l == NULL || ret) { 35 if (!retr) 36 printf("%d ", x->key); 37 if (x->r == NULL || retr) { 38 retr = (x == y->r); 39 x = y; 40 y = y->p; 41 ret = true; 42 } else { 43 y = x; 44 x = x->r; 45 ret = false; 46 } 47 } else { 48 y = x; 49 x = x->l; 50 } 51 } 52 printf("\n"); 53 }
12.1-5
12.2 查詢二叉搜索樹
除了基本的SEARCH外,還包括MINIMUM、MAXIMUM、SUCCESSOR、PREDESSOR等查詢操做。
12.2-5
12.2-6
12.2-7
12.2-8
12.2-9
12.3 插入和刪除
插入操做比較簡,基本二叉樹的刪除操做須要分類討論。書中使用了一個子函數TRANSPLANT簡化了一些基本操做,使得DELETE過程變得更加清晰。
插入和刪除的時間複雜度都是O(h).
12.3-2
12.3-3
12.3-4
不可交換,反例以下圖:
12.3-5
中文的《算法導論(第3版)》這道題徹底翻譯錯了,去看了一下英文的搞懂了題目作的。
如提示所示,就是利用後繼的屬性從新實現插入、刪除、查找函數。
求結點p的父節點的思路是先求得p所在子樹的最大值,該值所在結點的後繼就是p的父節點。 其他
操做均須要利用後繼的性質。以插入爲例。數據結構
1 void Tree_Insert(Tree_t *t, Node_t *z) { 2 Node_t *y = NULL; 3 Node_t *x = t->root; 4 while (x != NULL) { 5 y = x; 6 if (z->key < x->key) 7 x = x->l; 8 else 9 x = x->r; 10 } 11 if (y == NULL) { 12 t->root = z; // tree t was empty 13 z->succ = NULL; 14 } else if (z->key < y->key) { 15 Node_t *p = ParentOf(y); 16 z.succ = y; 17 p.succ = z; 18 } else { 19 z->succ = y->succ 20 y->succ = z; 21 } 22 }
12.4 隨機構建二叉搜索樹
算法導論不少章節都會講隨機算法在數據結構上的隨機化。並且都是大段大段的證實,挺犀利。隨機算法我我的打算單獨花時間學習,所以涉及到的題目都在第二遍讀算導的時候再作。
主要證實一棵有n個不一樣關鍵字的隨機構建的二叉搜索樹的指望高度爲O(lgn)。主要隨機搜索樹的不少基本操做的時間複雜度都是O(lgn)。隨機化的效率仍是很高的,其實能夠寫個隨機數據發生器,測試一下。函數