二叉搜索树的插入,查找,删除和遍历(c/c++)

二叉搜索树的建立

二叉搜索树的建立即为向二叉树中插入元素.开始插入第一个元素时,二叉搜索树是空树,直接申请一个内存空间将元素放入树中.再插入元素时,从根节点开始比较,若待插入的元素值较大,则树中节点向右走,若较小,则树中节点向左走,直到找到一个空位置,将节点插入.

二叉搜索树中查找元素

在二叉搜索树中查找元素时,先将元素与根节点值比较,若元素的值较小,则根节点向左走(root = root->left);若元素值较大,则根节点向右走直到找到相等大小的元素或者走到树的尽头.

二叉搜索树的删除

若树为空,则直接返回FALSE; 树不空,若待删除元素大于节点元素,则递归查找该节点的右子树;若待删除元素小于节点元素,则递归查找该节点的左子树;若待删除元素等于节点元素,则继续判断. (a)如果该节点是叶子节点,则直接将该节点置为空; (b)如果该节点只有左孩子,则把它的左孩子赋给该节点; (c)如果该节点只有右孩子,则把它的右孩子赋给该节点; (d)如果该节点(令该节点为p)既有左孩子又有右孩子,则找到该节点的右孩子的最左端的左孩子(令该节点为s),将这个节点的右孩子(s->right)赋给这个节点(s)的父节点(parent)的左孩子(parent->left = s->right),把待删除的节点(p)的左孩子(p->left)赋给该节点(s)的左孩子(s->left = p->left),把待删除的节点(p)的右孩子(p->right)赋给该节点(s)的右孩子(s->right = p->right).给函数中传来的节点赋值s.将p节点释放.

二叉搜索树的遍历

二叉搜索树作为树,也可以对其进行先序,中序,后序遍历,且其中序遍历相当于对树中元素从大到小的有序输出.

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#include <malloc.h>
using namespace std;
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef struct STnode* link;
struct STnode{
      int item;//元素值
      link l;//该节点的左子树链接
      link r;//该节点的右子树链接
};
//二叉搜索树的插入
link STinsert(link st, int num)
{
     if(st == NULL)
     {
         //申请内存空间
        link st = (link)malloc(sizeof(struct STnode));
        //为节点赋值
        st->item = num;
        //将左右子树置为空
        st->l = NULL;
        st->r = NULL;
        //将节点返回
        return st;
     }
    //printf("*%d* ", st->item);
    //该节点的值大于元素值的情况
    if(st->item > num)
    {
        //递归调用节点的左子树
        st->l = STinsert(st->l, num);
    }
    //该节点的值小于元素值的情况
    else if(st->item < num)
    {
        //递归调用节点的右子树
        st->r = STinsert(st->r, num);
    }
}
//二叉搜索树中元素的查找
Status STsearch(link h,int v)
{
    //空树,没有对应的值,查找失败
    if(h == NULL)
    {
        return FALSE;
    }
    //找到对应的元素值,查找成功
    if(v == h->item)
    {
        return TRUE;
    }
    //该节点的值大于元素值的情况
    if(v < h->item)
    {
        //递归调用节点的左子树
        STsearch(h->l, v);
    }
    //该节点的值小于元素值的情况
    else
    {
        //递归调用节点的右子树
        STsearch(h->r, v);
    }
}
//删除节点代码
Status BSTdelete(link *st, int item)
{
    link p = *st;
    //空树的情况
    if(!p)
    {
        return FALSE;
    }
    //找到了要删除的节点
    if(p->item == item)
    {
        //如果该节点是叶子结点
        if(!p->l && !p->r)
        {
            *st = NULL;
        }
        //如果该节点只有左孩子
        else if(p->l && !p->r)
        {
            *st = p->l;
        }
        //如果该节点只有右孩子
        else if(!p->l && p->r)
        {
            *st = p->r;
        }
        //如果该节点既有左孩子,又有右孩子
        else
        {
            //将该节点的左孩子表示出来
            link s = p->r;
            //如果该节点的右孩子没有左孩子
            if(!s->l)
            {
                s->l = p->l;
            }
            //如果该节点既有左孩子又有右孩子
            else
            {
                //定义s节点的父节点parent
                link parent = NULL;
                //找到s节点下最左端的左叶子节点
                while(s->l)
                {
                    parent = s;
                    s = s->l;
                }
                //将s点断开
                parent->l = s->r;
                //将s点换到p点
                s->l = p->l;
                s->r = p->r;
            }
            //连成树
            *st = s;
        }
        //将原节点释放掉
        free(p);
        return TRUE;
    }
    //如果元素值偏大
    else if(item > ((*st)->item))
    {
        //递归右子树
        BSTdelete(&(p->r), item);
    }
    //如果元素值偏小
    else
    {
        //递归左子树
        BSTdelete(&(p->l), item);
    }
}
//递归树前序遍历
void Traverse1(link tree)
{
    if(tree)
    {
        //先输出根结点
        printf("%d ", tree->item);
        //再递归其左子树
        Traverse1(tree->l);
        //再递归其右子树
        Traverse1(tree->r);
    }
}
//使用BST排序,即中序输出
void BSTsort(link h)
{
    if(h == NULL)
    {
        return;
    }
    //递归调用左子树
    BSTsort(h->l);
    //输出元素值
    printf("%d ", h->item);
    //递归调用右子树
    BSTsort(h->r);//递归调用
}
int main()
{
    int a[12] = {2, 5, 3, 7, 6, 1, 4, 11, 8, 10, 9, 12};
    link st = NULL;
    int i;
    //为空树中插入元素
    for(i = 0; i < 12; i++)
    {
        st = STinsert(st, a[i]);
    }
    //先序遍历该二叉搜索树
    Traverse1(st);
    printf("\n");
    //查找元素在二叉搜索树中是否存在
    if(STsearch(st, 7))
    {
        printf("7 在树中存在.\n");
    }
    else
    {
        printf("** 在树中不存在.\n");
    }
    //中序遍历二叉搜索树,元素从小到大有序输出
    BSTsort(st);
    printf("\n");
    //删除元素的情况
    int flag = BSTdelete(&st, 11);
    if(flag)
    {
        printf("删除成功!\n");
    }
    else
    {
        printf("要删除的元素不存在!\n");
    }
    //删除某个元素之后的先序遍历
    Traverse1(st);
    printf("\n");
    //删除某个元素之后的中序遍历
    BSTsort(st);
    printf("\n");
    return 0;
}

 

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/weixin_42480264/article/details/81837799
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞