二叉搜索树模板

花了3个多小时把二叉搜索树给好好学了下并把它写了出来,,具体怎么操作看下面代码注释,最麻烦的还是删除操作

代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

typedef struct BST{
    int x;  //关键字
    struct BST *p,*left,*right; //双亲节点,左孩子,右孩子
    
    BST(){}
    BST(int k){
        x = k;
        p = NULL,left = NULL,right=NULL;
    }
}BSTnode;

//************************查找************************

BSTnode* tree_search(BSTnode *&T,int k){     //递归查找
    
    if(T == NULL || T->x == k)  //等于NULL或找到K返回
        return T;
    if(k < T->x)                //比当前节点小就找左子树
        return tree_search(T->left,k);
    else                        //比当前节点大就找右子树
        return tree_search(T->right,k);
}

BSTnode* interative_tree_search(BSTnode *&T,int k){      //迭代查找
    BSTnode *t = T;
    while(t != NULL && t->x != k){
        if(k < t->x)
            t = t->left;
        else
            t = t->right;
    }
    return t;
}

//************************查找************************


//************************最大关键字查询,最小关键字查询,前驱和后继查询************************

BSTnode* tree_minmum(BSTnode *&T){   //最小关键字查询
    BSTnode *t = T;
    
    while(t->left != NULL){
        t = t->left;
    }
    return t;
}

BSTnode* tree_maxmum(BSTnode *&T){   //最大关键字查询
    BSTnode *t = T; 
    
    while(t->right != NULL){
        t = t->right;
    }
    return t;
}

BSTnode* tree_successor(BSTnode *&T){    //后继查询,后继就是大于T.x的最小关键字节点
    BSTnode *t = T,*y = NULL;

    if(t->right != NULL)                //如果右子树不为空直接求右子树的最小节点
        return tree_minmum(t->right);   
    
    y = t->p;

    while(y != NULL && y->right == t){
        t = y;
        y = t->p;
    }
    return y;
}

BSTnode* tree_predecessor(BSTnode *&T){  //前驱查询,前驱就是小于T.x的最大关键字节点
    BSTnode *t = T,*y = NULL;

    if(t->left != NULL)                 //如果左子树不为空直接求左子树的最大节点
        return tree_predecessor(t->left);
    
    y = t->p;                           
    
    while(y != NULL && y->left == t){   //这里就是没有左子树的情况,往上找,看看上面还有没有小于t.x的节点
        t = y;
        y = t->p;
    }
    return y;
}

//************************最大关键字查询,最小关键字查询,前驱和后继查询************************


//************************插入************************

void tree_insert(BSTnode *&T,int k){
    BSTnode *t = T,*y = NULL;

    BSTnode *z = new BSTnode(k);

    while(t != NULL){
        y = t;
        if(z->x < t->x)
            t = t->left;
        else
            t = t->right;
    }
    
    z->p = y;
    if(y == NULL)   //如果y为空
        T = z;
    else if(z->x < y->x)    //如果z的关键字小于y的关键字,那么放y的左边,否则就是右边
        y->left = z;
    else
        y->right = z;

}

//************************插入************************


//************************删除************************

void transplant(BSTnode *&T,BSTnode *&u,BSTnode *&v){//移动子树

    if(u->p == NULL)    //如果u是根节点,那么直接去掉
        T = v;
    else if(u == u->p->left)    //如果u是u->p的左孩子
        u->p->left = v; 
    else                        //如果u是u->p的右孩子
        u->p->right = v;
    if(v!=NULL){                //更新v的双亲
        v->p = u->p;
    }
}

void tree_delete(BSTnode *&T,BSTnode *&z){

    if(z->left == NULL)     //如果z的左孩子为空,那么直接把右子树移上来
        transplant(T,z,z->right);
    else if(z->right == NULL)   //如果z的右孩子为空,那么直接把左孩子移上来
        transplant(T,z,z->left);   
    else{                   //如果左右孩子都在
        
        BSTnode *y = tree_minmum(z->right); //找到右子树最小的节点
        if(y->p != z){                  //如果z不是y的双亲节点,那么说明y有不是z的双亲节点
            transplant(T,y,y->right);   //把y的左子树向上移,把y取出来
            y->right = z->right;    //把z连好的右子树放到y的右子树那边
            y->right->p = y;    //更新y的右子树的双亲
        }
        transplant(T,z,y);  //因为y是z的右子树最小节点,那么肯定没有左子树,直接上移,在把z的左子树放到y的左边,再更新y的左子树的双亲
        y->left = z->left;
        y->left->p = y;
    }
}

//************************删除************************


void inorder_input(BSTnode *&T){ //中序遍历输出
    if(T!=NULL){
        inorder_input(T->left);
        printf("%d ",T->x);
        inorder_input(T->right);
    }
}

int main(){

    int n;
    // scanf("输入节点数:%d",&n);
    // printf("\n输入关键字:");
    
    int x;
    BSTnode *T = NULL;
    int a[10] = {0,12,5,18,2,9,15,19,13,17};
    for(int i = 1;i<=9;i++){
        // int x;
        // scanf("%d",&x);
        tree_insert(T,a[i]);   //插入到树中
    }
    printf("before sequence is altered: \n");
    inorder_input(T);
    putchar('\n');

    printf("after digit 14 is inserted,sequence being print by the inorder: \n");
    tree_insert(T,14);
    inorder_input(T);
    putchar('\n');

    printf("after digit 5 is deleted,sequence being print by the inorder: \n");
    BSTnode *z = tree_search(T,5);
    if(z != NULL)
        tree_delete(T,z);
    inorder_input(T);
    putchar('\n');

    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值