算法:查找--2--二叉排序树

本文介绍了二叉排序树的概念及其特性,包括左子树所有节点值小于根节点,右子树所有节点值大于根节点。通过递归查找算法实现快速查找,插入算法用于新建或在已有二叉排序树中插入节点,删除算法则涉及对不同情况的处理。二叉排序树的性能依赖于其形状,形状不佳时查找效率会降低。
摘要由CSDN通过智能技术生成

二叉排序树:

二叉排序树,又称为二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树。
1.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3.它的左、右子树也分别为二叉排序树。
构造一颗二叉排序树的目的,其实并不是为了排序,而是为了提高查找和插入删除关键字的速度。
在一个有序数据集上的查找,速度总是要快于无序的数据集的,而二叉排序树这种非线性的结构,也有利于插入和删除的实现。

查找算法:

结点类:可以自行修改为泛型,参考前面的排序算法泛型的修改。

public class BitNode
{
    public int data;   
    public BitNode leftChild;
    public BitNode rightChild;
}
	/// <summary>
    /// 递归查找二叉排序树tree中是否存在key
    /// </summary>
    /// <param name="tree">二叉树根结点</param>
    /// <param name="key">查找的关键字</param>
    /// <param name="parent">指向tree的双亲,初始值为null</param>
    /// <param name="result">查找成功:result指向对应key的结点
    /// 查找失败:指向查找路径上访问的最后一个结点</param>
    /// <returns></returns>
    public bool SearchBST(BitNode tree, int key, BitNode parent, BitNode result)
    {
        if (tree == null)            //查找不成功
        {
            result = parent;
            return false;
        }
        else if (key == tree.data)  //查找成功
        {
            result = tree;
            return true;
        }
        else if (key < tree.data)
        {
            return SearchBST(tree.leftChild, key, parent, result);
        }
        else
        {
            return SearchBST(tree.rightChild, key, parent, result);
        }
    }

插入算法:可以用于新建二叉排序树

 /// <summary>
    /// 二叉排序树的插入:也可以用来新创建一颗二叉排序树
    /// </summary>
    /// <param name="tree">根结点</param>
    /// <param name="key">插入的key值</param>
    /// <returns></returns>
    public bool InsertBST(BitNode tree, int key)
    {
        BitNode p = null;
        BitNode insertNode = null;

        if (!SearchBST(tree, key, null, p)) //查找不成功
        {
            insertNode = new BitNode();
            insertNode.data = key;
            insertNode.leftChild = insertNode.rightChild = null;

            if (p == null)
            {
                tree = insertNode;               //插入s为新的根结点
            }
            else if (key < p.data)
            {
                p.leftChild = insertNode;        //插入s为左孩子
            }
            else
            {
                p.rightChild = insertNode;       //插入s为右孩子
            }

            return true;
        }
        else
        {
            return false;      //树中已有关键字相同的结点,不再插入
        }
    }

删除二叉排序树上的结点:推荐看书上的详细过程

 /// <summary>
    /// 删除二叉排序树上结点
    /// </summary>
    /// <param name="tree"></param>
    /// <param name="key"></param>
    /// <returns></returns>
    public bool DeleteBST(BitNode tree, int key)
    {
        if (tree == null)
        {
            return false;
        }
        else
        {
            if (key == tree.data)
            {
                return Delete(tree);
            }
            else if (key < tree.data)
            {
                return DeleteBST(tree.leftChild, key);
            }
            else
            {
                return DeleteBST(tree.rightChild, key);
            }
        }
    }

    private bool Delete(BitNode node)
    {
        BitNode p = null;
        BitNode s = null;

        if (node.rightChild == null)        //右子树空则只需重接它的左子树
        {          
            node = node.leftChild;
        }
        else if (node.leftChild == null)       //左子树空则只需重接它的右子树
        {           
            node = node.rightChild;
        }
        else                //左右子树均不空
        {
            p = node;
            s = node.leftChild;
            while (s.rightChild != null)
            {
                p = s;
                s = s.rightChild;
            }

            node.data = s.data; //s指向被删结点的直接前驱

            if (p != node)
            {
                p.rightChild = s.leftChild; //重接q的右子树
            }
            else
            {
                p.leftChild = s.leftChild;	//重接q的左子树
            }
        }

        return true;
    }

二叉排序树的查找性能取决于二叉排序树的形状,问题在于二叉排序树的形状是不确定的。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值