二叉排序树的插入、生成、删除及查找操作

二叉排序树的性质:

(1)若它的左子树不为空,左子树上所有节点的关键字均小于它的根节点的关键字;

(2)若它的右子树不为空,右子树上所有节点的关键字均大于它的根节点的关键字;

(3)它的左右子树也均为二叉排序树

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
    int key;
    struct node *lchild;
    struct node *rchild;
};


void InsertBST(struct node **bst,int key)
{
    struct node *s;

    if(*bst==NULL)
    {
        s=(struct node *)malloc(sizeof(struct node));  //申请新的节点
        s->key=key;
        s->lchild=NULL;
        s->rchild=NULL;        
    }
    else
    {
        if(key<(*bst)->key)
        {
            InsertBST(&((*bst)->lchild),key);
        }
        else
        {
            InsertBST(&((*bst)->rchild),key);
        }
    }
}

void CreatBST(struct node **bst)   //从键盘输入记录关键字,创建二叉排序树
{
    int key;

    *bst=NULL;
    scanf("%d",&key);
    while(key!=0)             //输入0时为结束标志
    {
        InsertBST(bst,key);
        scanf("%d",&key);
    }
}

void inOrder(struct node *root)  //中序遍历二叉排序树,root为根节点指针
{
    if(root!=NULL)
    {
        inOrder(root->lchild);
        printf("%d ",root->key);
        inOrder(root->rchild);
    }
}

//在以根指针bst所指的二叉排序树中,递归查找关键字为key的记录
//查找成功返回该记录节点指针,查找失败返回空指针
struct node *SearchBST(struct node *bst,int key) 
{
    if(!bst)
        return NULL;
    else
        if(bst->key==key)
            return bst;
        else
            if(bst->key>key)
                return SearchBST(bst->lchild,key);
            else
                return SearchBST(bst->rchild,key);
}

//在二叉排序树t中删除关键字为k的节点
struct node *DelBST(struct node *t,int k) 
{
    struct node *p,*f,*s,*q;

    p=t;
    f=NULL;

    while(p)  //查找关键字为k的待删除节点p
    {
        if(p->key==k)
            break;

        f=p; //f指向p的双亲节点

        if(p->key>k)
            p=p->lchild;
        else
            p=p->rchild;
    }

    if(p==NULL)
        return t;   //若找不到,返回原二叉排序树

    if(p->lchild==NULL)  //若p无左子树
    {
        if(f==NULL)
            t=p->rchild;  //p是原二叉排序树的根
        else
            if(f->lchild==p)    //p是f的左孩子
                f->lchild=p->rchild;
            else
                f->rchild=p->rchild;
            
            free(p); //释放被删除的节点
    }
    else
    {
        q=p;
        s=p->lchild;
        while(s->rchild)  //在p的左子树中查找最右下节点
        {
            q=s;
            s=s->rchild;
        }

        if(q==p)
            q->lchild=s->lchild; //将s的左子树链到q上
        else
            q->rchild=s->lchild;
        q->key=s->key;
    }

    return t;
}

void main()
{
    struct node *BST=NULL;

    int find_key; //要查找的关键字
    int insert_key; //要插入的关键字

    struct node *find_result; //存放查找结果

    printf("创建二叉排序树,输入序列(以0为结束标志):
");
    CreatBST(&BST);

    printf("二叉排序树中序遍历序列如下:
");
    inOrder(BST);

    printf("输入要查找的关键字:");
    scanf("%d",&find_key);

    find_result=SearchBST(BST,find_key);

    if(find_result!=NULL)
    {
        printf("要查找的记录存在,值为:%d
",find_result->key);
        find_result=DelBST(BST,find_key);;
        printf("查找到的记录被删除后的中序遍历后的序列如下:
");
        inOrder(find_result);
    }
    else
        printf("该记录不存在!只能进行插入操作!");
    printf("
输入要插入的记录的关键字:");
    scanf("%d",&insert_key);
    InsertBST(&BST,insert_key);
    printf("插入新的记录后的中序遍历后的序列如下:
");
    inOrder(BST);

    system("pause");


}