用c语言写二叉排序树

#include<stdio.h>
#include<stdlib.h>
typedef int datatype;
typedef struct node//二叉排序树结点定义
{
    datatype key;//结点值
    struct node *lchild,*rchild;//左右孩子指针
}bsnode;
typedef bsnode *bstree;


//二叉排序树的插入
void insertbstree(bstree *t,datatype x)
{
    bstree f,p;
    p=*t;
    while(p)//查找插入位置
    {
        if(x==p->key)
        return;//若二叉排序树t中已有key,则无需插入
        f=p;//f用于保存新结点的最终插入位置
        p=(x<p->key)?p->lchild:p->rchild;
    }
    p=(bstree)malloc(sizeof(bsnode));//生成待插入的新节点
    p->key=x;
    p->lchild=p->rchild=NULL;
    if(*t==NULL)
    *t=p;//原数为空
    else
     if(x<f->key)
     f->lchild=p;
     else
     f->rchild=p;
    }
    //根据输入的结点序列,建立一颗二叉排序树,并返回根节点的地址
    bstree creatbstree(void)
    {
      bstree t=NULL;
      datatype key;
      printf("\n请输入一个以-1未结束标志的结点序列:\n");
      scanf("%d",&key);//输入一个关键字
      while(key!=-1)
      {
          insertbstree(&t,key);//将key插入二叉排序树t
          scanf("%d",&key);
      }
      return t;//返回建立的二叉排序树的根指针
    }
    //二叉排序树的非递归查找
    void bssearch1(bstree t,datatype x,bstree *p,bstree *q)
    {
        //q返回待查结点x在二叉排序树的地址,p返回待查结点x的父节点地址
        *p=NULL;
        *q=t;
        while(*q)
        {
            if(x==(*q)->key)
            return;
            *p=*q;
            *q=(x<(*q)->key)?(*q)->lchild:(*q)->rchild;
        }
        return;
    }
    //二叉排序树的递归查找
    bstree bssearch2(bstree t,datatype x)
    {
        //在二叉排序树t中查找关键字为x的结点
        if(t==NULL||x==t->key)
        return t;
        if(x<t->key)
        return bssearch2(t->lchild,x);//递归的在左子树中检索
        else
        return bssearch2(t->rchild,x);//递归的在右子树中检索
    }
    //在二叉排序树t中删除结点值为x的结点
    bstree delbstree(bstree t,datatype x)
    {
        bstree p,q,child;
        bssearch1(t,x,&p,&q);//查找被删节点
        if(q)//找到了待删除节点
        {
            if(q->lchild==NULL&&q->rchild==NULL)//被删节点为叶子结点
            {
                if(p)//待删除节点有双亲
                {
                    if(p->lchild==q)
                    p->lchild=NULL;
                    else
                    p->rchild=NULL;
                }
                else
                 t=NULL;//被删结点为树根
                 free(q);
            }
            else
             if(q->lchild==NULL)//被删结点左子树为空,用其右子树代替
             {
                 if(p)//被删结点的双亲结点不为空
                 {
                     if(p->lchild==q)
                     p->lchild=q->rchild;//q是其双亲结点的左孩子
                     else
                      p->rchild=q->rchild;//q是其双亲节点的右孩子
                 }
                 else
                  t=q->rchild;
                  free(q);
             }
             else
             if(q->rchild==NULL)
             {
                 if(p)//被删结点的双亲结点不为空
                 {
                     if(p->lchild==q)
                     p->lchild=q->lchild;
                     else
                     p->lchild=q->lchild;
                 }
                 else
                 t=q->lchild;
                 free(q);
             }
             else//被删结点的左右子树均不为空,用右子树代替被删结点
             {
                 child=q->rchild;
                 while(child->lchild)
                 child=child->lchild;
                 child->lchild=q->lchild;
                 if(p)
                 {
                     if(p->lchild==q)
                     p->lchild=q->rchild;
                     else
                     p->rchild=q->rchild;
                 }
                 else
                  t=q->rchild;
                  free(q);
             }
        }
        return t;
    }
    //中序遍历二叉排序树
    void inorder(bstree t)
    {
        if(t)
        {
            inorder(t->lchild);
            printf("%4d",t->key);
            inorder(t->rchild);
        }
    }
    int main()
    {
        bstree p,q;
        datatype x;
        bstree t;
        t=creatbstree();//创建二叉排序树
        inorder(t);
        printf("\n请输入一个待查找的结点值:\n");
        scanf("%d",&x);
        bssearch1(t,x,&p,&q);
        if(q)
        printf("\nFOUND!");
        else
        printf("\nNOT FOUND!");
        printf("\n请输入一个待插入的结点值:\n");
        scanf("%d",&x);
        insertbstree(&t,x);
        inorder(t);
        printf("\n请输入一个待删除的结点值:\n");
        scanf("%d",&x);
        t=delbstree(t,x);//删除指定结点
        inorder(t);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值