二叉搜索树的查找、插入、删除

#include <stdio.h>

#include <malloc.h>

 

struct node    //节点的数据结构

{

    int data;

    struct node *left;

    struct node *right;

};

 

--- --- --- --- --- --- --- 查 找 --- --- --- --- --- --- ---

void BSTreeSearch(struct node * p,int x)

{

    while(p)

    {

        if(x < (*p).data) p = (*p).left;

        else if(x > (*p).data) p = (*p).right;

        else { printf("Found"); return; }      

    }

    printf("Not found");

}

 

--- --- --- --- --- --- --- 插 入 --- --- --- --- --- --- ---

struct node * BSTreeInsert(struct node * root,int x)

{

    struct node *p = root, *pp = 0, *e;

    while(p)  //找合适的插入位置(必作为叶节点插入)

    {

        pp = p;

        if(x < (*p).data) p = (*p).left;

        else if(x > (*p).data) p = (*p).right;

        else { printf("Already exists!"); return root; }       

    }

    e = (struct node *)malloc(sizeof(struct node));

    (*e).data = x; (*e).left = 0; (*e).right = 0;

    if(root)  //非空树

    {

        if(x < (*pp).data) (*pp).left = e;

        else (*pp).right = e;

    }

    else root = e; //插到空树中

    return root;

}

 

--- --- --- --- --- --- --- 删 除 --- --- --- --- --- --- --- ---

删除,要删除的节点有3种情况:

1. 叶节点 => 直接删除,父节点指针置零

2. 只有一个子节点 => 用其父节点指向其子节点

3. 2个子节点 => 用左子树中的最大元素替换后,转为第12种情况

--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --

struct node * BSTreeDelete(struct node * root,int x)

{  

//pp: 要删除的节点,ppp是其父节点,p是其子节点

    //t:  pp的左子树中的最大节点,pt是其父节点

    struct node * ppp,*pp=root,*p,*t,*pt;

    while(pp && (*pp).data != x)

    {

        ppp = pp;

        if(x < (*pp).data) pp = (*pp).left;

        else pp = (*pp).right; 

    }

    if(!pp) { printf("Not Found!"); return root; }

 

    if((*pp).left && (*pp).right) //pp2个孩子

    {  

//pp的左子树最大节点

        pt = pp; t = (*pp).left;

        while((*t).right)

        { pt = t; t = (*t).right; }

        //替换后,pp指向t

        (*pp).data = (*t).data; pp = t; ppp = pt;

    }

 

    //此时pp只有01个孩子

    if((*pp).left) p = (*pp).left;

    else p = (*pp).right;

 

    //删除pp

    if(pp == root) root = p; //若要删的是根

    else  //pp的父节点ppp指向pp的子节点p

    {

        if(pp == (*ppp).left) (*ppp).left = p;

        else (*ppp).right = p;

    }

    return root;

}

 

--- --- --- --- --- --- --- 调 用 --- --- --- --- --- --- ---

void main()

{

    struct node a,b,c,d,e,*root;

    a.data = 3; a.left = &b; a.right = &c;

    b.data = 1; b.left = 0;  b.right = &d;

    c.data = 5; c.left = &e; c.right = 0;

    d.data = 2; d.left = 0;  d.right = 0;

    e.data = 4; e.left = 0;  e.right = 0;  

    root = &a;

 

    BSTreeSearch(root,4);

    root = BSTreeInsert(root,6);

    root = BSTreeDelete(root,5);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值