二叉排序树

#include <stdio.h>
#include <stdlib.h>
 
typedef int KeyType; // 定义节点关键码的类型为整型
typedef struct node  // 二叉排序树的结构体
{
    KeyType key;                  // 树节点的关键码
    struct node *lchild, *rchild; // 左右孩子指针
} node, *BiSortTree;
 
void CreateBST(BiSortTree *T);            // 构造二叉排序树
void InsertBST(BiSortTree *T, KeyType x); // 向T中插入关键码值为 x 的节点
void DeleteBST(BiSortTree *T, KeyType x); // 删除T中关键码值为 x 的节点
void TraverseBST(BiSortTree T);           // 中序遍历BST
int SearchBST(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f);
int SearchBST_Recursive(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f);
// 在T中查找关键码值为 x 的节点,若找到则返回1,p指向该节点,f指向该节点双亲节点;否则返回0
 
int main(void)
{
    BiSortTree T, p, f;
 
    p = f = NULL;
    CreateBST(&T);
    printf("遍历:");
    TraverseBST(T);
    printf("\n");
 
    printf("查找 98 :");
    int flag = SearchBST(T, 98, &p, &f);
    if (flag)
        printf("查找成功!\n");
    else
        printf("查找失败!\n");
 
    printf("递归查找 100 :");
    flag = SearchBST_Recursive(T, 100, &p, &f);
    if (flag)
        printf("查找成功!\n");
    else
        printf("查找失败!\n");
 
    printf("插入 100 :");
    InsertBST(&T, 100);
    TraverseBST(T);
    printf("\n");
 
    printf("删除 98 :");
    DeleteBST(&T, 98);
    TraverseBST(T);
    printf("\n");
 
    return 0;
}
 
void CreateBST(BiSortTree *T) // 构造二叉排序树
{
    KeyType x;
 
    printf("请输入若干整数构建BST,以 -1 结束:");
 
    *T = NULL;
    scanf("%d", &x);
    while (x != -1) {
        InsertBST(T, x);
        scanf("%d", &x);
    }
}
// 在T中查找关键码值为 x 的节点,若找到则返回1,*p指向该节点,*f为*p双亲节点;否则返回0
int SearchBST(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f)
{
    *p = T;
    while (*p) {
        // 查找成功
        if ((*p)->key == x)
            return 1;
        else {
            // 在左子树继续查找
            if (x < (*p)->key) {
                *f = *p;
                *p = (*p)->lchild;
            }
            // 在右子树继续查找
            else {
                *f = *p;
                *p = (*p)->rchild;
            }
        }
    }
 
    return 0; // 查找失败
}
int SearchBST_Recursive(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f)
{
    // 树空时,查找失败
    if (!T)
        return 0;
    // 查找成功
    else if (x == T->key) {
        *p = T;
        return 1;
    }
    // 在左子树继续查找
    else if (x < T->key)
        return SearchBST_Recursive(T->lchild, x, p, &T);
    // 在右子树继续查找
    else
        return SearchBST_Recursive(T->lchild, x, p, &T);
}
void InsertBST(BiSortTree *T, KeyType x) // 向T中插入关键码值为 x 的节点
{
    BiSortTree p, f, s;
 
    f = p = NULL;
    // 若树中不存在关键码值为 x 的节点,则插入
    if (!SearchBST(*T, x, &p, &f)) {
        s = (node *)malloc(sizeof(node)); // 申请节点并赋值
        s->key = x;
        s->lchild = NULL;
        s->rchild = NULL;
 
        // 若树为空,将新申请的节点作为根节点
        if (!*T)
            *T = s;
        else {
            // 插入节点为f的左孩子
            if (x < f->key)
                f->lchild = s;
            // 插入节点为f的右孩子
            else
                f->rchild = s;
        }
    }
}
void DeleteBST(BiSortTree *T, KeyType x) // 删除T中关键码值为 x 的节点
{
    BiSortTree p, f, s, s_parent;
    /**
     * p:要删除的节点
     * f:p的双亲结点
     * s:p的中序前驱节点
     * s_parent:s的双亲结点
     */
 
    p = f = NULL;
    // 若树中存在关键码值为 x 的节点,则删除
    if (SearchBST(*T, x, &p, &f)) {
        // 被删除节点无左右孩子
        if (!p->lchild && !p->rchild) {
            // 若删除的是根节点
            if (p == *T) {
                *T = NULL;
                free(p);
            }
            // 若删除的不是根节点
            else {
                if (p->key < f->key)
                    f->lchild = NULL;
                else
                    f->rchild = NULL;
                free(p);
            }
        }
        // 被删除节点有右孩子无左孩子
        else if (!p->lchild && p->rchild) {
            // 若删除的是根节点
            if (p == *T) {
                *T = p->rchild;
                free(p);
            }
            // 若删除的不是根节点
            else {
                if (p->key < f->key)
                    f->lchild = p->rchild;
                else
                    f->rchild = p->rchild;
                free(p);
            }
        }
        // 被删除节点有左孩子无右孩子
        else if (p->lchild && !p->rchild) {
            // 若删除的是根节点
            if (p == *T) {
                *T = p->lchild;
                free(p);
            }
            // 若删除的不是根节点
            else {
                if (p->key < f->key)
                    f->lchild = p->lchild;
                else
                    f->rchild = p->lchild;
                free(p);
            }
        }
        // 被删除节点有左右孩子
        else {
            s_parent = p;
            s = p->lchild;
            while (s->rchild) // 查找被删除节点中序前驱节点
            {
                s_parent = s;
                s = s->rchild;
            }
            p->key = s->key;
            if (s_parent == p)
                s_parent->lchild = s->lchild;
            else
                s_parent->rchild = s->lchild;
            free(s);
        }
    }
}
void TraverseBST(BiSortTree T) // 中序遍历BST
{
    if (T) {
        TraverseBST(T->lchild);
        printf("%d, ", T->key);
        TraverseBST(T->rchild);
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值