二叉搜索樹

性質

  • 二叉搜索樹;對於樹中的每個節點 x,x 的左子樹全部節點的 key 不大於 x.key;x 的右子樹的 key 不小於 x.key;若是按照 std::multimap 使用的 Compare 規則來解釋,則若 x 的左子樹的 key 均在 x.key 以前或之上;x 的右子樹的 key 均在 x.key 之上(即位置相同)或者以後.算法

時間複雜度

  • 樹的高度 h 與節點個數 n 的關係;h∈[lgn(以2爲底),n],這個很好推的.函數

  • 遍歷操做;Θ(n)spa

  • 查找;前驅;後繼,等其餘操做;與 h 成正比,即 Θ(h).指針

操做算法

  • 查找;最小值,最大值;找前驅,後繼;這類不會修改二叉搜索樹結構的操做算法,能夠參考 libstdcxx/include/bits/stl_tree.h 中實現的紅黑樹.code

// 變量說明;
T;表示一顆二叉搜索樹,
    T.root;指針,指向着二叉搜索樹的根節點.
節點;
    key;節點的鍵;
    parent,left,right;指針,指向着節點的父節點,孩子節點;若節點沒有父節點,或者孩子節點,則置爲0.
使用 < 來肯定鍵值的前後關係;

插入

// z;指針;指向着待插入的節點.其中 z->key 爲節點的鍵;z->parent,left,right 爲 0.
insert(T,z)
    y = 0;
    x = T.root;
    insert_left = true; // 若爲真,則代表 z 應該插入在 y 的左子樹上.

    // 肯定 z 的插入位置.
    while(x != 0)
        y = x;
        insert_left = z->key < x->key;
        x = insert_left ? x->left : x->right;
    // 當循環結束時,x==0,y 指向着 z 的父節點,而 insert_left 代表了插入位置.

    // 在 z 與 y 之間創建聯繫.    
    z->parent = y;
    if( y == 0)
        T.root = z;
    else
        if (insert_left)
            y->left = z;
        else
            y->right = z;

刪除

  • 刪除,能夠分爲4種狀況來分別對待(見上圖),能夠從中序遍歷的結果來理解,以(c)狀況爲例;在刪除z以前,中序遍歷的結果是"l左子樹;l;l右子樹;z;y;x左子樹;x;x右子樹";因此在刪除 z 以後,中序遍歷的結果應該是"l左子樹;l;l右子樹;y;x左子樹;x;x右子樹",也即須要對二叉搜索樹作一些調整,使得調整後中序遍歷結果爲"l左子樹;l;l右子樹;y;x左子樹;x;x右子樹";具體調整過程見(c)左圖--->右圖結構.it

// u,v;指針,指向着 T 中的某一節點,其中 v 能夠爲0.
// 該函數在 v 與 u 的父節點之間創建鏈接,即讓 v 替代 u 成爲 u 父節點的孩子節點.
traslate(T,u,v){
    up = u->parent;
    
    // up ---> v;
    if(up == 0)
        T.root = v;
    else if(up->left == u)
        up->left = v;
    else
        up->right = v;
    
    // v ---> up;
    if(v!=0)
        v->parent = up;

    // 此時;up <---> v;
}

// z;指針;指向着待刪除的節點.
erase(T,z){
    // 狀況 b;
    if(z->right == 0)
        translate(T,z,z->left);
    
    // 狀況 a;
    else if(z->left == 0)
        translate(T,z,z->right);

    else
        y = 後繼(z);
        // 狀況 d 
        if(y->parent != z)
            translate(T,y,y->right);
            y->right = z->right;
            z->right->parent = y;
            // 此時狀況 d 轉化爲 狀況 c;
        // 狀況 c;
        y->left = z->left;
        z->left->parent = y;
        translate(T,z,y);
}
相關文章
相關標籤/搜索