zoukankan      html  css  js  c++  java
  • 二叉排序树的创建删除中序输出&&平衡树

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef struct Node{
        Node *l, *r;
        int v;
        Node(){l = NULL; r = NULL;}
    }*tree, Node;
    tree build(tree p, int v){
        if(p == NULL){
            p = new Node();
            p->v = v;
            return p;
        }
        if(v < p->v)
            p->l = build(p->l, v);
        else if(v > p->v)
            p->r = build(p->r, v);
        else
            return p;
        return p;
    }
    void Delete(tree &T, int k){
        Node *p = T;
        Node *q, *s, *f;
        f = NULL;
        while(p){
            if(p->v == k){
                break;
            }
            f = p;
            if(k < p->v){
                p = p->l;
            }
            else{
                p = p->r;
            }
        }
        q = p;
        if(!p)return;
        if(p->l && p->r){
            p = p->l;
            while(p->r){
                s = p;
                p = p->r;
            }
            q->v = p->v;
            s->r = p->l;
            delete(p);
            return;
        }
        else if(p->l){
            q = p; p = p->l;
        }
        else{
            q = p; p = p->r;
        }
        //cout << "*" << endl;
        if(!f)T = p;
        else if(q == f->l)f->l = p;
        else f->r = p;
        delete(q);
    }
    
    void InOrder(tree p){
        if(p == NULL)return;
        InOrder(p->l);
        printf("%d ", p->v);
        InOrder(p->r);
    }
    
    int main(){
        int N;
        while(~scanf("%d", &N)){
            tree p;
            p = NULL;
            int v;
            for(int i = 0; i < N; i++){
                scanf("%d", &v);
                p = build(p, v);
            }
            InOrder(p);
            
            int m;
            scanf("%d", &m);
            for(int i = 0; i < m; i++){
                scanf("%d", &v);
                Delete(p, v);
                InOrder(p);
            }
        }
        return 0;
    }

    1)  对α的左儿子的左子树进行一次插入(左旋)

    其中D是新插入的节点,红色节点K2是失去平衡的节点。需要对K1和K2进行左旋调整即将K1作为根,将K2作为K1的左子树,K1的右子树调整为K2的左子树。如下图所示

    进行左旋变换   

    2)对α的右儿子的右子树进行一次插入(右旋)

    将K2的右子树更改为K1的左子树,K1的左子树更改为K2即完成的右旋,如下图所示

    进行右旋

    3)对α的左儿子的右子树进行一次插入(左右双旋)

    左右双旋这里的左右指的是对α的左儿子的右子树进行插入时需要旋转。先对K1和K2进行右旋(跟第四种情况类似),然后再对K3和K2进行左旋,最终实现平衡。如下图所示

    进行一次右旋进行一次左旋

    4)对α的右儿子的左子树进行一次插入(右左双旋)

    右左双旋:先对K1和K2进行左旋,然后在对K2和K3进行右旋,最终实现平衡。如下图所示

    进行一次左旋进行一次右旋

    平衡树:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    struct TreeNode{
      int v;
      int H;
      struct TreeNode *l;
      struct TreeNode *r;     
           
    };
    
    typedef struct TreeNode *AvlTree, *Position;
    
    AvlTree FreeTree(AvlTree T){
            if(T != NULL){
                 FreeTree(T->l);
                 FreeTree(T->r);
                 delete(T);
            }
            return NULL;    
    }
    int Height(Position p){
        if(p == NULL)
            return -1;
        return p->H;
        
     }
    void pushup(Position &K){
        K->H = max(Height(K->l), Height(K->r)) + 1;
    }
     
    Position SingleRotateWithLeft(Position K2){
        Position K1 = K2->l;
        K2->l = K1->r;
        K1->r = K2;
        pushup(K1);
        pushup(K2);
        return K1;
    }
    Position SingleRotateWithRight(Position K2){
        Position K1 = K2->r;
        K2->r = K1->l;
        K1->l = K2;
        pushup(K1);
        pushup(K2);
        return K1;
    }
    
    
    Position DoubleRotateWithLeft(Position K3){
        K3->l = SingleRotateWithRight(K3->l);
        K3 = SingleRotateWithLeft(K3);
    }
    Position DoubleRotateWithRight(Position K3){
        K3->r = SingleRotateWithLeft(K3->r);
        K3 = SingleRotateWithRight(K3);
    }
    
    AvlTree insert(int x, AvlTree T){
            if(T == NULL){
                 T = new TreeNode();
                 T->v = x;
                 T->H = 0;
                 T->l = T->r = NULL;     
            }
            else if(x < T->v){
                 T->l = insert(x, T->l);
                 if(Height(T->l) - Height(T->r) == 2){
                     if(x < T->l->v)
                         T = SingleRotateWithLeft(T);
                     else
                         T = DoubleRotateWithLeft(T);
                 }
            }
            else if(x > T->v){
                 T->r = insert(x, T->r);
                 if(Height(T->r) - Height(T->l) == 2){
                     if(x > T->r->v)
                         T = SingleRotateWithRight(T);
                     else
                         T = DoubleRotateWithRight(T);
                 }
            }
            pushup(T);
            return T;
    }
    AvlTree Visit(int X, AvlTree T){
        if(T == NULL)
            return NULL;
        if(X < T->v)
            return Visit(X, T->l);
        if(X > T->v)
            return Visit(X, T->r);
        return T;
    }
    void PreVisit(AvlTree T){
        if(T == NULL)
            return;
        printf("%d ", T->v);
        PreVisit(T->l);
        PreVisit(T->r);
    }
    void InVisit(AvlTree T){
        if(T == NULL)
            return;
        InVisit(T->l);
        printf("%d ", T->v);
        InVisit(T->r);
    }
    int main(){
        AvlTree T = FreeTree(NULL);
       // puts("**");
       int i;
        for(i = 1; i <= 7; i++)  
            T = insert(i, T);  
        for(i = 16; i >= 10; i--)  
            T = insert(i, T);  
        T = insert(8, T);  
        T = insert(9, T);
        
        printf("InOrder:  ");  
        InVisit(T);  
        printf("
    PreOrder: ");  
        PreVisit(T);  
        putchar('
    ');
        return 0;    
    }


    参考博客:http://blog.csdn.net/zitong_ccnu/article/details/11097663#

  • 相关阅读:
    分享一个在线生成站点地图SiteMap制作工具
    去掉tppabs冗余代码,怎样批量去掉tppabs代码
    js文字无缝滚动
    史上最全的Win8快捷键大全
    原码, 反码, 补码
    Java [Leetcode 136]Single Number
    拉格朗日对偶
    随机森林与GBDT
    GBDT(Gradient Boosting Decision Tree)算法&协同过滤算法
    Java [Leetcode 165]Compare Version Numbers
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5579993.html
Copyright © 2011-2022 走看看