数据结构(七)——查找之二叉排序树

代码中所用到的结构体

typedef struct Node
{
   
    int elem;//存放数据
    struct Node *lchild, *rchild;
    struct Node *prev;
} TreeNode, *BiTree; //定义树节点的结构体
typedef struct tree
{
   
    BiTree root;
}Tree,*pTree;

构造二叉排序树

  • 以第一个输入的数据作为排序二叉树的根。
  • 对数数据的输入分为6种情况:
  • 1.当树不存在的时候,当前数据作为树的根;
  • 2.当树中存在此数据时,打印“此数据已存在”;
  • 3.输入数据小于当前结点且当前结点无左儿子,则输入数据作为当前结点的左儿子;
  • 4.输入数据小于当前结点且当前结点有左儿子,则将当前结点指针移动到左儿子,继续比较;
  • 5.输入数据大于当前结点且当前结点无右儿子,则输入数据作为当前结点的右儿子;
  • 6.输入数据大于当前结点且当前结点有右儿子,则将当前结点指针移动到右儿子,继续比较;
  • 结束条件为输入 -1
void CreateBST(pTree T)//构造二叉排序树
{
   
    int e=0;//初始化
    while(1)//while循环建立二叉排序树
    {
   
        printf("Please input the child of BST:");
        printf("(input will over when you input -1.)\n");
        scanf("%d",&e);//插入的数据
        getchar();
        if(e==-1)//非法判断
        {
   
            break;
        }
        BiTree n1=(BiTree)malloc(sizeof(TreeNode));//申请空间
        BiTree n2=T->root;//初始化
        n1->elem=e;
        n1->lchild=NULL;
        n1->rchild=NULL;
        n1->prev=NULL;
        if(T->root==NULL)//当树不存在时
        {
   
            T->root=n1;
        }
        else//当树存在时
        {
   
            while(1)//实现二叉树插入
            {
   
                if(e==n2->elem)//若树中存在此元素
                {
   
                    printf("this elem has existed!\n");
                    break;
                }
                if(e>n2->elem&&n2->rchild==NULL)
                {
   
                    n2->rchild=n1;
                    n1->prev=n2;
                    break;
                }
                else if(e>n2->elem)
                {
   
                    n2=n2->rchild;
                }
                else if(e<n2->elem&&n2->lchild==NULL)
                {
   
                    n2->lchild=n1;
                    n1->prev=n2;
                    break;
                }
                else if(e<n2->elem)
                {
   
                    n2=n2->lchild;
                }
            }
        }
    }
}

删除二叉排序树的结点

删除可能出现的几种情况

  • 二叉排序树不存在。
  • 二叉排序树中无将删除的结点。
  • 二叉排序树中存在要删除的结点,并执行删除。

这里,我对第三种查找到了二叉排序树中存在该节点并删除进行展开讨论。

二叉排序树中的删除节点的三种情况
1.即将删除的节点为叶结点。

  • 执行方法,将该叶结点删除,且将原本指向该叶结点的指针指向NULL;

2.即将删除的节点仅存在左子树或者仅存在右子树。(这里以仅存在左子树为例)

  • 寻找即将删除节点的左子树的最右下节点(即左子树中的最大结点),将其赋值给即将删除的结点,赋值完成后再对该最右下结点进行处理。
  • 这里要注意的是,这里删除节点的值被左子树中最大结点覆盖的同时,左子树中的最大结点也要随之删除,这里也要对其讨论是否存在左子树进行讨论。

3.即将删除的结点即存在右子树,也存在左字数。

  • 这里有两种选择,以左子树中的最右下结点(即左子树中的最大结点)进行替换,或是以右子树中的最左下节点(即右子树中的最小结点)进行替换。
  • 同样要注意的是,在替换的时候,要对被拿去替换的点进行讨论,看其是否存在左子树,或右子树。
void DeleteNode(pTree T)//删除二叉排序树的结点
{
   
    int e;
    BiTree n=T->root;
    BiTree n1=NULL;
    BiTree n2=NULL;
    printf("Please input the elem you want to delete:\n");
    scanf("%d"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值