二叉排序树的创建删除中序输出&&平衡树

#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("\nPreOrder: ");  
    PreVisit(T);  
    putchar('\n');
    return 0;    
}


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

 

posted @ 2016-06-13 11:14  handsomecui  阅读(401)  评论(0编辑  收藏  举报