選擇樹
-
概念:假設有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);
}