【基礎知識】 之 Binary Search Tree 二叉搜索樹


前言

這個系列是畢業找工作的復習筆記,希望可以和廣大正准備畢業的童鞋一起打牢基礎,迎接各種筆試……為了應付中英文筆試,關鍵詞都用英文進行標注,這樣就不怕面對英文題目了。之所以開始這一系列是因為之前在參加微軟筆試的時候,被一道stable sorting的選擇題給卡住了,才發現自己的基本功什么時候變得這么差了。既然要找工作就要好好復習,從最基礎的開始。算法的部分來自《The Algorithm Design Manual》的筆記。

結構特點

二叉搜索樹的特點是,小的值在左邊,大的值在右邊,即

比如:

這樣的結構有一個好處是很容易獲得最大值(Maximum)、最小值(minimum)、某元素的前驅(Precursor)、某元素的后繼(Successor)。

最大值:樹的最右節點。

最小值:樹的最左節點。

某元素前驅:左子樹的最右。

某元素的后繼:右子樹的最左。

基本操作

二叉搜索樹的基本操作包括searching、traversal、insertion以及deletion。

(代碼為了省地方沒有按照規范來寫,真正寫代碼的時候請一定遵照規范)

① searching

tree * search_tree(tree *l, item_type x){
    if(l == null) return NULL;
    if(l->item == x) return l;
    if(x < l->item){
        return (search_tree(l->left, x));
    }   
    if(x > l->item){
        return (search_tree(l->right, x));
    }
}

時間復雜度為O(h),h為樹的高度。

② traversal

由於小的節點在左邊,大的節點在右邊,因此使用中序(in-order)遍歷可以方便的得到一個sorted list。

void traverse_tree(tree *l){
    if(l != NULL){
        traverse_tree(l->left);
        process_item(l->item);
        traverse_tree(l->right);
    }
}

時間復雜度為O(n),n為樹的總結點數。

③ insertion

insert_tree(tree **l, item_type x, tree *parent){
    tree *p; /*temporary pointer*/
    if(*l == NULL){
        p = malloc(sizeof(tree));
        p->item = x;
        p->left = p->right = NULL;
        p->parent = parent;
        *l = p;
        return;
    }
    if(x < (*l)->item){
        insert_tree(&((*l)->left), x, *l);
    }else{
        insert_tree(&((*l)->right), x, *l);
    }
}

時間復雜度為O(h),h為樹的高度。

④deletion

在刪除節點時有三種情況:

1)要刪除的節點為葉節點

  那么直接刪除即可。

2)要刪除的節點有一個子節點

  那么刪除掉該節點,並用其唯一的子節點代替自己的位置即可。

3)要刪除的節點有兩個子節點

  那么首先要找到該節點的右子樹的最小值節點k,然后將該k替換掉待刪除節點。

最壞情況下,時間復雜度為O(h)+指針的移動開銷。

 

進階

由上可知,二叉搜索樹的dictionary operation(包括search、insertion、deletion)的時間復雜度均與O(h)相關,h為樹的高度(log n),如果按照上述的insertion方法構建樹,那么構建出來的樹的形狀各異,特別是當輸入序列有序時,更會退化到鏈表的程度。所以,如果能用某種方法,將樹的高度降低到最小,那么其dictionary operation的時間開銷均可以降低,不過相對而言構建樹的開銷將增大。為了降低二叉搜索樹的高度而提出了平衡二叉樹(Balanced Binary Tree)的概念。它要求左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。這樣就可以將搜索樹的高度盡量減小。常用算法有紅黑樹、AVL、Treap、伸展樹等。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM