数据结构和算法(9):二叉排序树

本文详细介绍了如何在编程中实现二叉排序树,包括创建节点类、添加数据(Insert方法)、以及中序、前序、后续和层序遍历,同时涵盖删除节点的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

基本概念

代码实现二叉排序树

创建节点类

添加Add方法

中序遍历

前序遍历

后续遍历

层序遍历

添加删除方法


基本概念

二叉树是一种很好的排序应用模式,因为在建立二叉树的同时,数据已经经过初步的比较,并按照二叉树的建立规则来存放数据。其规则如下:

  1. 第一个输入数据作为此二叉树的树根。

  2. 之后的数据以递归的方式与树根进行比较,小于树根置于左子树,大于树根置于右子树。

代码实现二叉排序树

创建节点类

首先创建一个节点类,这个节点包含数据Data,左孩子Left的引用,右孩子Right的引用。

public class Node
{
    public int Data;
    public Node Left;
    public Node Right;

    public Node(int data)
    {
        Data = data;
        Left = null;
        Right = null;
    }
}

添加Add方法

然后是添加数据的操作。数据以递归的方式与树根进行比较,小于树根置于左子树,大于树根置于右子树。

public void Insert(int data)
{
    _root = InsertRec(_root, data);
}

// 递归插入函数
private Node InsertRec(Node root, int data)
{
    // 如果当前节点为空,创建一个新节点并返回
    if (root == null)
    {
        root = new Node(data);
        return root;
    }

    // 如果插入的数据小于当前节点的数据,递归插入到左子树
    if (data < root.Data)
    {
        root.Left = InsertRec(root.Left, data);
    }
    // 如果插入的数据大于当前节点的数据,递归插入到右子树
    else if (data > root.Data)
    {
        root.Right = InsertRec(root.Right, data);
    }

    return root;
}

中序遍历

从上面的规则我们知道,左子树内的值一定小于树根,而左子树的值一定大于树根。因此,只需要利用“中序遍历”方式就可以得到从小到大排序好的数据。如果想从大到小排序,则可将最后结果置于堆栈内再一次弹出(Pop)即可。

public void Inorder()
{
    InorderRec(_root);
}

// 递归中序遍历函数
private void InorderRec(Node root)
{
    if (root != null)
    {
        InorderRec(root.Left);
        Console.Write(root.Data + " ");
        InorderRec(root.Right);
    }
}

前序遍历

public void Preorder()
{
    PreorderRec(_root);
}

private void PreorderRec(Node root)
{
    if (root != null)
    {
        Console.Write(root.Data + " ");
        PreorderRec(root.Left);
        PreorderRec(root.Right);
    }
}

后续遍历

public void Postorder()
{
    PostorderRec(_root);
}

private void PostorderRec(Node root)
{
    if (root != null)
    {
        PostorderRec(root.Left);
        PostorderRec(root.Right);
        Console.Write(root.Data + " ");
    }
}

层序遍历

public void LevelOrder()
{
    LevelOrderRec(_root);
}

private void LevelOrderRec(Node root)
{
    if (root == null)
    {
        return;
    }

    Queue<Node> queue = new Queue<Node>();
    queue.Enqueue(root);

    while (queue.Count > 0)
    {
        Node currentNode = queue.Dequeue();
        Console.Write(currentNode.Data + " ");

        if (currentNode.Left != null)
        {
            queue.Enqueue(currentNode.Left);
        }

        if (currentNode.Right != null)
        {
            queue.Enqueue(currentNode.Right);
        }
    }
}

添加删除方法

public void Delete(int data)
{
    _root = DeleteRec(_root, data);
}

// 递归删除函数
private Node DeleteRec(Node root, int data)
{
    // 如果当前节点为空,直接返回
    if (root == null)
    {
        return root;
    }

    // 如果要删除的数据小于当前节点的数据,递归删除左子树中的节点
    if (data < root.Data)
    {
        root.Left = DeleteRec(root.Left, data);
    }
    // 如果要删除的数据大于当前节点的数据,递归删除右子树中的节点
    else if (data > root.Data)
    {
        root.Right = DeleteRec(root.Right, data);
    }
    // 如果当前节点就是要删除的节点
    else
    {
        // 如果当前节点只有右子树或没有子树,直接返回右子树
        if (root.Left == null)
        {
            return root.Right;
        }
        // 如果当前节点只有左子树,直接返回左子树
        else if (root.Right == null)
        {
            return root.Left;
        }

        // 如果当前节点有两个子树,找到右子树中的最小值节点,替换当前节点的值
        root.Data = MinValue(root.Right);
        // 删除右子树中的最小值节点
        root.Right = DeleteRec(root.Right, root.Data);
    }

    return root;
}

// 查找二叉搜索树中的最小值节点
private int MinValue(Node root)
{
    int minValue = root.Data;
    while (root.Left != null)
    {
        minValue = root.Left.Data;
        root = root.Left;
    }
    return minValue;
}

以下是完整的代码

  public class Node
    {
        public int Data;
        public Node Left;
        public Node Right;

        public Node(int data)
        {
            Data = data;
            Left = null;
            Right = null;
        }
    }

    public class BinarySearchTree
    {
        private Node _root;

        public BinarySearchTree()
        {
            _root = null;
        }

        public void Insert(int data)
        {
            _root = InsertRec(_root, data);
        }

        // 递归插入函数
        private Node InsertRec(Node root, int data)
        {
            // 如果当前节点为空,创建一个新节点并返回
            if (root == null)
            {
                root = new Node(data);
                return root;
            }

            // 如果插入的数据小于当前节点的数据,递归插入到左子树
            if (data < root.Data)
            {
                root.Left = InsertRec(root.Left, data);
            }
            // 如果插入的数据大于当前节点的数据,递归插入到右子树
            else if (data > root.Data)
            {
                root.Right = InsertRec(root.Right, data);
            }

            return root;
        }

        public void Inorder()
        {
            InorderRec(_root);
        }

        // 递归中序遍历函数
        private void InorderRec(Node root)
        {
            if (root != null)
            {
                InorderRec(root.Left);
                Console.Write(root.Data + " ");
                InorderRec(root.Right);
            }
        }

        public void Delete(int data)
        {
            _root = DeleteRec(_root, data);
        }

        // 递归删除函数
        private Node DeleteRec(Node root, int data)
        {
            // 如果当前节点为空,直接返回
            if (root == null)
            {
                return root;
            }

            // 如果要删除的数据小于当前节点的数据,递归删除左子树中的节点
            if (data < root.Data)
            {
                root.Left = DeleteRec(root.Left, data);
            }
            // 如果要删除的数据大于当前节点的数据,递归删除右子树中的节点
            else if (data > root.Data)
            {
                root.Right = DeleteRec(root.Right, data);
            }
            // 如果当前节点就是要删除的节点
            else
            {
                // 如果当前节点只有右子树或没有子树,直接返回右子树
                if (root.Left == null)
                {
                    return root.Right;
                }
                // 如果当前节点只有左子树,直接返回左子树
                else if (root.Right == null)
                {
                    return root.Left;
                }

                // 如果当前节点有两个子树,找到右子树中的最小值节点,替换当前节点的值
                root.Data = MinValue(root.Right);
                // 删除右子树中的最小值节点
                root.Right = DeleteRec(root.Right, root.Data);
            }

            return root;
        }
        public void Preorder()
        {
            PreorderRec(_root);
        }

        private void PreorderRec(Node root)
        {
            if (root != null)
            {
                Console.Write(root.Data + " ");
                PreorderRec(root.Left);
                PreorderRec(root.Right);
            }
        }

        public void Postorder()
        {
            PostorderRec(_root);
        }

        private void PostorderRec(Node root)
        {
            if (root != null)
            {
                PostorderRec(root.Left);
                PostorderRec(root.Right);
                Console.Write(root.Data + " ");
            }
        }

        public void LevelOrder()
        {
            LevelOrderRec(_root);
        }

        private void LevelOrderRec(Node root)
        {
            if (root == null)
            {
                return;
            }

            Queue<Node> queue = new Queue<Node>();
            queue.Enqueue(root);

            while (queue.Count > 0)
            {
                Node currentNode = queue.Dequeue();
                Console.Write(currentNode.Data + " ");

                if (currentNode.Left != null)
                {
                    queue.Enqueue(currentNode.Left);
                }

                if (currentNode.Right != null)
                {
                    queue.Enqueue(currentNode.Right);
                }
            }
        }

        // 查找二叉搜索树中的最小值节点
        private int MinValue(Node root)
        {
            int minValue = root.Data;
            while (root.Left != null)
            {
                minValue = root.Left.Data;
                root = root.Left;
            }
            return minValue;
        }


    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值