二叉排序树

二叉排序树,也称作二叉查找树,一般定义为或者是空树,或者是满足以下条件的二叉树:

(1)若它的左子树不空,则左子树上所有记录的关键字值均小于根记录关键字的值。

(2)若它的右子树不空,则右子树上所有记录的关键字均大于根记录关键字的值。

(3)  它的左、右子树本身也是二叉排序树。

 

#include<stdio.h>
typedef int keytype;                  //数据域值类型
typedef struct node                   
{
    keytype data;                     //数据域
    struct node *left,*right;         //左、右链域
}Bitree;                              //二叉排序树结点数据类型 

!-----------二叉排序树的查找

1.递归查找算法

Bitree *F = NULL;       //存放双亲结点指针,插入和删除时使用

Bitree *find(Bitree *T,keytype x)
{
    if(T==NULL) return NULL;
    if(T-data==x) return T;
    else
    {
        F = T;
        if(T->data>x) find(T->left,x);
        else find(T->right,x);
    }
}

2.非递归查找算法

Bitree *F = NULL;       //存放双亲结点指针,插入和删除时使用

Bitree *searchbst(Bitree *T,keytype key)
{
    Bitree *C = NULL;
    while(T!=NULL)
    if(T->data==key) {C=T;break;} 
    else if(key<T->data)
        {F=T;T=T->left;}
        else
        {F=T;T=T->right;}
    return C;
}

!-------------二叉排序树的插入

向二叉树中插入一个新元素的算法思路:

(1)在插入之前,先使用查找算法在树中检查要插入的元素是否存在。

(2)搜索成功:树中已有这个元素,不再插入,可能会做删除操作。

(3)搜索失败:树中没有关键字值等于给定值的结点,将新元素接入到查找停止处。

Bitree *insertbst(Bitree *T,keytype key)
{
    Bitree *C,*s;
    C = searchbst(T,key);
    if(C==NULL)
    {
        s = (Bitree*)malloc(sizeof(Bitree));
        s->data = key; s->left = s->right = NULL;
        if(F==NULL) T=s;
        else if(key<F->data)F->left = s;
            else F->right = s;
    }
    return T;
}

!---------二叉排序树的创建

Bitree *creatbst()
{
    keytype key;
    Bitree *T = NULL;
    scanf("%d",&key);
    while(key!=-1)
    {
        T = insertbst(T,key);
        scanf("%d",&key);
    }
    return T;
}

!-------二叉排序树的删除

(1)删除叶子结点,只需将其双亲结点中指向它的指针置空,再释放它即可。

(2)被删结点无右子树,可以用它的左孩子结点顶替它的位置,再释放它。

(3)被删结点无左子树,可以用它的右孩子结点顶替它的位置,再释放它。

(4)被删结点同时有左子树和右子树,用左子树的最右下结点替换被删结点。

int deletebst(Bitree *T,keytype key)
{
    Bitree *p,*s,*q;
    p = searchbst(T,key);
    if(!p){printf("not exist\n");return 0;}
    if(p->left==NULL)                   //左子树空,则重接其右子树
    {q=p;p=p->right;}
    else if(p->right==NULL)             //右子树为空,则重接其左子树
        {q=p;p=p->left;}
        else                            //左右子树都不空
        {q=p;s=p->left; 
         while(s->right!=NULL)
         {q=s;s=s->>right;}             //找到p的左子树的最右下结点s
         if(q!=p) q->right=s->left;     //重接q的右子树
         else q->left = s->left;        //重接q的左子树
         q=s;p->data = s->data;         //用s结点的值替换p结点的值
        }
    if(F==NULL) T=p;                    //若被删除结点为根节点,则将p改为根结点
    else if(q!=s)                       //左子树为空或右子树为空的结点p与其双亲结点重新链接
        if(key<F->data) F->left = p;
        else F->right=p;
    free(q);
    return 1;
}

 

posted @ 2019-01-02 14:35  自强·  阅读(319)  评论(0编辑  收藏  举报