選擇樹
-
概念:假設有k個已經排序的序列,並且想要將其合並成一個單獨的排序序列。每個排好序的序列叫走一個
歸並段
。 -
暴力算法:假設總共有n個數字,每次取k個歸並串最小或者最大的一個數,比較k-1次得到所有數中最大或者最小的樹,存入新空間中,接着一直這樣比較...需要比較的次數是n*(k-1)
-
選擇樹算法:可以構造完全二叉樹的數組表示法。初始狀態如下:
接着將上圖最小的6放到新序列中,然后用15替換最下層的6,再進行規范化,接着選出最小,如下:
可以看到,每次的比較次數是O(logk),時間復雜度是O(nlogk)
判定樹
- 概念:以著名的
8枚硬幣
的問題進行說明。假定有8枚硬幣a-h,其中一枚硬幣是偽造的。偽造的硬幣可能比標准的重或者輕,所以可能的結果有16種情況。
-
如圖,無論是什么情況,經過3次比較一定出結果
-
代碼如下:
char Compare(int a, int b) { if(a > b) return '>'; else if(a < b) return '<'; else return '='; } void comp(int x,int y,int z) { if(x>z) cout << x << "heavy"; else cout << y << "light"; } void eightcoins() { int a,b,c,d,e,f,g,h; cin >> a >> b >> ... >> h; switch(Compare(a+b+c,d+e+f)) { case '=': if(g>h) comp(g,h,a) else comp(h,g,a); break; case '>': switch(Compare(a+d,b+e)) { case '=': comp(c,f,a); break; case '>': comp(a,e,b); break; case '<': comp(b,d,a); break; } break; case '<': switch(Compare(a+d,b+e)) { case '=': comp(f,c,a); break; case '>': comp(d,b,a); break; case '<': comp(e,a,b); break; } break; } }
查找樹
一般來說,查找樹指的是二叉查找樹,其查找過程是從根結點一直向下查找,時間復雜度為O(logn)。
對查找二叉樹進行中序遍歷,是個遞增序列
定義如下:
- 若它的左子樹不空,則其左子樹上任意結點的關鍵字的值都小於根結點關鍵字的值
- 若右子樹不空,則其右子樹上任意結點的關鍵字的值都大於根結點的關鍵字的值
- 它的左右子樹又是一個二叉查找樹
代碼實現:
- 定義數據結構:
struct celltype{ records data; celltype *lchild, *rchild; }; typedef celltype *BST;
- 插入數據:
void Insert(records R, BST &F) { if(F == NULL) { F = new celltype; F->data = R; F->lchild = NULL; F->rchild = NULL; } else if(R.key < F->data.key) Insert(R,F->lchild); else if(R.key > F->data.key) Insert(R,F->rchild); }
- 刪除數據:
//刪除關鍵字最小的結點並且返回其數據 records DeleteMin(BST & F) { records tmp; BST P; if(F->lchild == NULL) { P = F; tmp = F->data; F = F->rchild; delete P; return tmp; } else return DeleteMin(F->lchild); } void Delete(keytype k,BST &F) { if(F) { if(k < F->data.key) Delete(k,F->lchild); else if(k > F->data.key) Delete(k,F->rchild); else //查找成功 { if(F->lchild == NULL) F = F->rchild; else if(F->rchild == NULL) F = F->lchild; else F->data = DeleteMin(F->rchild); } } }
- 查找數據
BST Serach(keytype k,BST F) { if(F == NULL) return NULL; else if( k == F->data.key) return F; else if(k < F->data.key) return Search(k,F->lchild); else if(k > F->data.key) return Search(k,F->rchild); }