對一棵高度爲h的二叉查找樹,動態集合操做SEARCH、MINIMUM、MAXIMUM、SUCCESSOR和PREDECESSOR等的運行時間均爲O(h)。算法
NODE* treeSearch(NODE *rt,T k) { if (rt==NULL || k==rt->key) return rt; if (k<rt->key) return treeSearch(rt->l,k); else return treeSearch(rt->r,k); } NODE* iterativeTreeSearch(NODE *rt,T k) { while (rt!=NULL && k!=rt->key) { if (k<rt->key) rt=rt->l; else rt=rt->r; } } NODE* treeMinimum(NODE *rt) { while (rt->l!=NULL) rt=rt->l; return rt; } NODE* treeMaximum(NODE *rt) { while (rt->r!=NULL) rt=rt->r; return rt; } NODE* treeSuccessor(NODE *rt) { if (rt->r!=NULL) return treeMinimum(rt->r); NODE* pt=rt->p; while (pt!=NULL && rt==pt->r) { rt=pt; pt=pt->p; } return pt; }
12.2-1 假設在某二叉查找樹中,有1到1000之間的一些數,現要找出363這個數。下列的結點序列中,哪個不多是所檢查的序列。code
b) c) e) 不是blog
12.2-2 寫出TREE-MINIMUM和TREE-MAXIMUM過程的遞歸版本。遞歸
NODE* getMinimum(NODE *rt) { if (rt->l!=NULL) return getMinimum(rt->l); return rt; }
NODE* treePredecessor(NODE *rt) { if (rt->l!=NULL) return treeMaximum(rt->l); NODE* pt=rt->p; while (pt!=NULL && rt==pt->l) { rt=pt; pt=pt->p; } return pt; }
如圖 20∈A,10∈B,20>10。ip
12.2-5 證實:若是二叉查找樹中的某個結點有兩個子女,則其後繼沒有左子女,其前驅沒有右子女。get
若該結點有左子女,則其前驅爲左子樹中的最大值即左子樹的最左,顯然沒有左子女。it
若該節點有右子女,則其後繼爲右子樹中的最大值即右子樹的最右,顯然沒有右子女。class
12.2-6 考慮一棵其關鍵字各不相同的二叉查找樹T。證實:若是T中某個結點x的右子樹爲空,且x有一個後繼y,那麼y就是x的最低祖先,且其餘左孩子也是x的祖先。file
考慮二叉查找樹的中序遍歷,對一個結點k,left[k]爲根的子樹中最大元素的後繼是k,k的後繼在right[k]中,right[k]爲根的子樹中最大元素的後繼即爲left[p[k]]或right[p[k]]的後繼問題。由此可知,x的第一個右祖先y就是x的後繼,y的左兒子和左兒子的左兒子等等都是x的祖先。遍歷
12.2-7 對於一棵包含n個結點的二叉查找樹,其中序遍歷能夠這樣來實現:先用TREE-MINIMUM找出樹中的最小元素,而後再調用n-1次TREE-SUCCESSOR。證實這個算法的運行時間爲Θ(n)。
TREE-MINIMUM運行時間爲O(h)。n-1次TREE-SUCCESSOR實質上是非遞歸不用棧實現中序遍歷的過程,所以運行時間爲Θ(n)。
12.2-8 證實:在一棵高度爲h的二叉查找樹中,不管從哪個結點開始,連續使用k次調用TREE-SUCCESSOR所需的時間是O(k+h)。
每一個結點最多訪問三次?
12.2-9 設T爲一棵其關鍵字均不相同的二叉查找樹,並設x爲一個葉子結點,y爲其父結點。證實:key[y]或者是T中大於key[x]的最小關鍵字,或者是T中小於key[x]的最大關鍵字。
若x爲y的左孩子,查找y的前驅,顯然最左孩子爲x。所以key[y]爲大於key[x]的最小關鍵字。
若x爲y的右孩子,查找y的後繼,顯然最右孩子爲x。所以key[y]爲小於key[x]的最大關鍵字。