C#二叉树的插入、遍历、查询

二叉树是指一个节点最多有两个子节点Left,right。节点值Left<当前<Right。第一个插入的节点叫做根节点。后面增加一个节点,小的值放的左子节点上,大的值放在右子节点上。其实每添加一个节点,都只是将新节点挂在原节点上,并没有改变原有的树结构。

在visual studio 2017中新建控制台程序DemoBinaryTree,新建类BinaryTree.cs。测试程序代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoBinaryTree
{
    /// <summary>
    /// 二叉树:每个节点最多有两个子节点的树结构(左节点、右节点)
    /// </summary>
    public class BinaryTree
    {
        /// <summary>
        /// 根节点
        /// </summary>
        public Node RootNode;
        /// <summary>
        /// 二叉树每次添加一个节点都是在不改变原来的树结构的基础上,增加一个悬挂节点
        /// </summary>
        /// <param name="data"></param>
        public void InsertNode(int data)
        {
            Node currentNode = new Node(data);
            if (RootNode == null)
            {
                RootNode = currentNode;
                return;
            }
            Node node = RootNode;
            //从根节点开始遍历,如果需要插入的节点的值小于当前节点,则向左子节点遍历。否则向右子节点遍历。直到找到子节点为空,循环终止
            while (true)
            {
                if (data < node.Weight)
                {
                    if (node.LeftNode == null)
                    {
                        node.LeftNode = currentNode;
                        break;
                    }
                    else
                    {
                        node = node.LeftNode;
                    }
                }
                else
                {
                    if (node.RightNode == null)
                    {
                        node.RightNode = currentNode;
                        break;
                    }
                    else
                    {
                        node = node.RightNode;
                    }
                }
            }
        }

        /// <summary>
        /// 中序遍历:访问完所有左儿子后,再访问根节点,最后访问右儿子
        /// </summary>
        /// <param name="node"></param>
        public void DisplayMiddle(Node node)
        {
            if (node != null)
            {
                DisplayMiddle(node.LeftNode);
                Console.WriteLine(node.Weight);
                DisplayMiddle(node.RightNode);
            }
        }

        /// <summary>
        /// 中序遍历,非递归
        /// </summary>
        public void DisplayLoop(Node node)
        {
            Node currentNode = node;
            Stack<Node> stack = new Stack<Node>();
            while (true)
            {
                while (currentNode != null)
                {
                    stack.Push(currentNode);
                    currentNode = currentNode.LeftNode;
                }
                if (stack.Count > 0)
                {
                    currentNode = stack.Pop();
                    Console.WriteLine(currentNode.Weight);
                    currentNode = currentNode.RightNode;
                }
                else
                {
                    //如果堆栈内的元素全部弹出,则退出循环
                    break;
                }
            }
        }

        /// <summary>
        /// 获取最小值:最深层的左节点
        /// </summary>
        /// <returns></returns>
        public int GetMin()
        {
            Node node = RootNode;
            while (node != null && node.LeftNode != null)
            {
                node = node.LeftNode;
            }
            return node.Weight;
        }

        /// <summary>
        /// 获取最大值:最深层的右节点
        /// </summary>
        /// <returns></returns>
        public int GetMax()
        {
            Node node = RootNode;
            while (node != null && node.RightNode != null)
            {
                node = node.RightNode;
            }
            return node.Weight;
        }

        /// <summary>
        /// 二叉树查找:查找二叉树中是否存在指定值的节点,没有返回null
        /// </summary>
        /// <param name="data">要寻找节点的值</param>
        /// <returns></returns>
        public Node FindNode(int data)
        {
            Node node = RootNode;
            while (node != null)
            {
                if (data == node.Weight)
                {
                    break;
                }
                else if (data < node.Weight)
                {
                    node = node.LeftNode;
                }
                else
                {
                    node = node.RightNode;
                }
            }
            return node;
        }
    }

    /// <summary>
    /// 二叉树的节点:由节点本身的值(或权重)、左子节点、右子节点组成
    /// </summary>
    public class Node
    {
        /// <summary>
        /// 节点的值,或权重
        /// </summary>
        public int Weight { get; set; }
        /// <summary>
        /// 左子节点
        /// </summary>
        public Node LeftNode { get; set; }
        /// <summary>
        /// 右子节点
        /// </summary>
        public Node RightNode { get; set; }

        /// <summary>
        /// 构造函数:以一个权重值实例化一个节点
        /// </summary>
        /// <param name="weight">节点的值,权重</param>
        public Node(int weight)
        {
            this.Weight = weight;
        }
    }
}
 

在默认的Program.cs中的Main函数中,添加测试代码,如下:

static void Main(string[] args)
        {
            BinaryTree bt = new BinaryTree();
            //初始化二叉树,也就是将指定的值添加到二叉树中,第一个值就是根节点
            bt.InsertNode(23);
            bt.InsertNode(49);
            bt.InsertNode(12);
            bt.InsertNode(39);
            bt.InsertNode(6);
            bt.InsertNode(88);
            bt.InsertNode(20);
            Console.WriteLine("中序遍历:递归");
            bt.DisplayMiddle(bt.RootNode);

            Console.WriteLine("中序遍历:循环");
            bt.DisplayLoop(bt.RootNode);

            Console.WriteLine("该二叉树的最小值:{0}", bt.GetMin());
            Console.WriteLine("该二叉树的最大值:{0}", bt.GetMax());
            Node node1 = bt.FindNode(35);
            Console.WriteLine("测试查找值【35】是否存在:{0}", node1 != null);
            Node node2 = bt.FindNode(39);
            Console.WriteLine("测试查找值【39】是否存在:{0}", node2 != null);
            Console.ReadLine();
        }

程序运行结果,截图:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值