二叉排序树的建立,插入,删除,查找,以及遍历

C++和数据结构的新手试炼,删除函数写的非常冗杂,望大神多多指教~

#include <iostream>
#define ElemType int
using namespace std;

//二叉树结构体
typedef struct tree {
    ElemType data;
    struct tree* lchild, * rchild;
}*BiTree, BTNode;

//二叉排序树插入新节点
int BST_Insert(BiTree& T, ElemType x) {      //这里引用指针T,不然本函数需返回指针
    if (T == NULL) {                         //新建节点
        T = (BiTree)malloc(sizeof(BTNode));
        T->data = x;
        T->lchild = T->rchild = NULL;
        return 1;
    }
    else if (x == T->data)
        return 0;
    else if (x < T->data)
        return BST_Insert(T->lchild, x);
    else
        return BST_Insert(T->rchild, x);
}

//查找关键字为x的节点,并返回指针
BTNode* BST_Search(BiTree T, ElemType x, BTNode*& p) {
    p = NULL;    //指针p用来指向被查找节点的双亲,便于插入或删除操作。
                 //若所查找结点为根节点,则p=NULL
    while (x != T->data && T != NULL) {
        p = T;
        if (x < T->data)
            T = T->lchild;
        else
            T = T->rchild;
    }
    return T;
}

//删除二叉树中值为x的个节点
void BST_Delete(BiTree& T, ElemType x) {
    BTNode* p = (BTNode*)malloc(sizeof(BTNode));  //指针p用来指向被查找节点的双亲
    BTNode* q = BST_Search(T, x, p);              //查找关键字为x的节点,并返回指针

    if (p != NULL) {                              //要删除节点不是根节点,存在双亲结点
        if (q->lchild == NULL && q->rchild == NULL) {      //叶节点

            if (p->lchild == q)
                p->lchild = NULL;
            else
                p->rchild = NULL;
            free(q);
        }
        else if (q->lchild == NULL && q->rchild != NULL) {   //有右孩子节点
            if (p->lchild == q)
                p->lchild = q->rchild;
            else
                p->rchild = q->rchild;
            free(q);
        }
        else if (q->lchild != NULL && q->rchild == NULL) {   //有左孩子节点
            if (p->lchild == q)
                p->lchild = q->lchild;
            else
                p->rchild = q->lchild;
            free(q);
        }
        else {                              //左右孩子节点都存在,用直接后继代替要删除的节点
                                            //直接后继就是右子树的最左的孩子节点
            BTNode* r = q->rchild;
            p = q;
            while (r->lchild) {
                p = r;
                r = r->lchild;
            }
            q->data = r->data;
            if (p == q) {                   //q的直接后继就是自己的右孩子
                q->rchild = r->rchild;
                free(r);
            }
            else {                          //q的直接后继是右子树的最左的孩子节点
                p->lchild = NULL;
                free(r);
            }
        }
    }
    else {                                               //要删除的是根节点
        if (q->lchild == NULL && q->rchild == NULL) {    //根节点又是叶节点,树只有一个节点
            T = NULL;
            free(q);
        }
        else if (q->lchild == NULL && q->rchild != NULL) {  //有右孩子节点,右孩子成为根节点
            T = q->rchild;
            free(q);
        }
        else if (q->lchild != NULL && q->rchild == NULL) { //有左孩子节点,左孩子成为根节点
            T = q->lchild;
            free(q);
        }
        else {                               //左右孩子节点都存在,用直接后继代替要删除的节点
                                             //直接后继就是右子树的最底层左孩子节点
            BTNode* r = q->rchild;
            p = q;
            while (r->lchild) {
                p = r;
                r = r->lchild;
            }
            q->data = r->data;
            if (p == q) {                           //q的直接后继就是自己的右孩子
                q->rchild = r->rchild;
                free(r);
            }
            else {                                 //q的直接后继是右子树的最左的孩子节点
                p->lchild = NULL;
                free(r);
            }
        }
    }

    cout << "删除成功" << endl;
}

//用n个数的关键字数组建立一个二叉排序树
void BST_Creat(BiTree& T, ElemType str[], int n) {
    T = NULL;
    for (int i = 0; i < n; i++) {
        BST_Insert(T, str[i]);
    }
}



//访问函数
void visit(BiTree T) {
    cout << T->data << " ";
    return;
}

//递归中序遍历
void InOrder(BiTree T) {
    if (T) {
        InOrder(T->lchild);
        visit(T);
        InOrder(T->rchild);
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值