二叉树是指一个节点最多有两个子节点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();
}
程序运行结果,截图: