二叉排序树数据结构和搜索

二叉排序树(简称BST)又称二叉查找(搜索)树,其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
      (1) 若它的左子树非空,则左子树上所有记录的值均小于根记录的值;
      (2) 若它的右子树非空,则右子树上所有记录的值均大于根记录的值;
      (3) 左、右子树本身又各是一棵二叉排序树。


在二叉排序树中插入一个新记录,要保证插入后仍满足BST性质。其插入过程是:若二叉排序树T为空,则创建一个key域为k的结点,将它作为根结点,否则将k和根结点的关键字比较,若二者相等,则说明树中已有此关键字k,无须插入,直接返回0;若k < T->key,则将k插入根结点的左子树中,否则将它插入右子树中。

删除操作:

删除操作必须首先进行查找,假设在查找过程结束时,已经保存了待删除结点及其双亲结点的地址。指针变量p指向待删除的结点,指针变量q指向待删除结点p的双亲结点。删除过程如下:
      (1) 若待删除的结点是叶子结点,直接删去该结点。如图(a)所示,直接删除结点9。这是最简单的删除结点的情况。

 

    (2) 若待删除的结点只有左子树而无右子树。根据二叉排序树的特点,可以直接将其左子树的根结点放在被删结点的位置。如图(b)所示,*p作为*q的右子树根结点,要删除*p结点,只需将*p的左子树(其根结点为3)作为*q结点的右子树。

    (3) 若待删除的结点只有右子树而无左子树。与(2)情况类似,可以直接将其右子树的根结点放在被删结点的位置。如图(c)所示,*p作为*q的左子树根结点,要删除*p结点,只需将*p的右子树(其根结点为8)作为*q结点的右子树。

      (4) 若待删除的结点同时有左子树和右子树。根据二叉排序树的特点,可以从其左子树中选择关键字最大的结点或从其右子树中选择关键字最小的结点放在被删去结点的位置上。假如选取左子树上关键字最大的结点,那么该结点一定是左子树的最右下结点。如图(d)所示,若要删除*p(其关键字为5)结点,找到其左子树最右下结点4,它的双亲结点为2,用它代替*p结点,并将其原来的左子树(其根结点为3)作为原来的双亲结点2的右子树。

其二叉树的建立查找删除

都在下面的程序中了

 

#include <stdio.h>
#include 
<stdlib.h>
#define MAX 100
typedef 
struct node
{
    
int key;  //2叉树点的值 这里假定都为正整数
    struct node *lchild, *rchild;
}
BSTnode;

int InsertBST(BSTnode *&b,int key)
{
    
if(b==NULL)          //用插入法来建树  这里是树一开始为0时
    {
        b
=(BSTnode*)malloc(sizeof(BSTnode));
        b
->key=key;
        b
->lchild=b->rchild=NULL;
        
return 1;
    }

    
if(key==b->key) return 0;  //这里是点已经存在了 

    
if(key<b->key) 
        
return    InsertBST(b->lchild,key);
    
else 
        
return InsertBST(b->rchild,key);
}

BSTnode 
*CreateBST(int a[ ],int n)
{
    BSTnode 
*b=NULL;   //A中存放点的值
    int i=0;
    
while(i<n)
    
{
        InsertBST(b,a[i]);
        i
++;
    }

    
return b;
}


BSTnode 
*SearchBST(BSTnode *b, int key)
{
    
/*
    if(b!=NULL) printf("%d ",b->key);
    else printf("no this key ");
    if(b->key==key) printf(" ");
*/
  //这里可以追踪搜索过程

    
if(b==NULL||b->key==key)
        
return b;
    
if(key<b->key)
        
return SearchBST(b->lchild,key);
    
else 
        
return SearchBST(b->rchild,key);
}


//这是删除点函数所要调用的函数
void Delete1(BSTnode *b,BSTnode *&r)
{      //如果二叉树的点有2个分支的话  要先找到左边分支的最右分支的点
    if(r->rchild!=NULL)
        Delete1(b,r
->rchild);
    
else
    
{
        BSTnode 
*q;
        b
->key=r->key;        //把这个点的值赋给要删除的点
        q=r;    
        r
=r->lchild;                //把这个点按没有右分支来处理
        free(q);
    }

}

void Delete(BSTnode *&b)  //这个函数为删掉该点,并维护好树的结构
{
    BSTnode 
*p;
    
if(b->rchild==NULL)    //这个点没有右分支
    {
        p
=b;
        b
=b->lchild;    //这时候只要把左分支点换到这个位置
        free(p);
    }

    
else
        
if(b->lchild==NULL)   //这个点没有左分支
        {
            p
=b;
            b
=b->rchild;   //这时只要把右分支的点换到这个位置
            free(p);
        }

        
else
            Delete1(b,b
->lchild);  //这个点2个分支都有
}




int DeleteBST(BSTnode *&b,int key)   //这个是删除节点函数  需要调用前面2个函数
{                                                          //首先要先找到点
    if(b==NULL) return 0;
    
if(key<b->key)
        DeleteBST(b
->lchild,key);
    
else
        
if(key>b->key)
            DeleteBST(b
->rchild,key);
        
else
        
{
            Delete(b); 
//这个函数是去掉点的函数
            return 1;
        }

}

int main()
{
    
int i,j,n;
    
int a[MAX];
    printf(
"intput the number of the ver ");
    scanf(
"%d",&n);
    printf(
"input the ver ");
    
for(i=0;i<n;i++)
        scanf(
"%d",&a[i]);
    BSTnode 
*b;
    b
=CreateBST(a,n);
    BSTnode 
*p;
    p
=SearchBST(b,a[n-2]);  //假定都是对a[n-2]这个节点进行操作
    DeleteBST(b,a[n-2]);
    SearchBST(b,a[n
-2]);
    
return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值