直接上C#代码
/*
* author:codingriver
* 20181016 21:46
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TreeTest
{
/// <summary>
/// 打印输出公共接口
/// </summary>
interface IPrint
{
void Print();
void Write();
string ToString();
}
class Tree<T> where T : IComparable<T>, IPrint
{
private Node<T>root;
public Node<T> Root
{
get { return root; }
set{root=value;}
}
/// <summary>
/// 先序遍历(根节点-->左孩子-->右孩子)
/// </summary>
public void FrontRootOrder()
{
Root.FrontRootOrder();
}
/// <summary>
/// 中序遍历(左孩子-->根节点-->右孩子)
/// </summary>
public void InRootOrder()
{
Root.InRootOrder();
}
/// <summary>
/// 后序遍历(左孩子-->右孩子-->根节点)
/// </summary>
public void BackRootOrder()
{
Root.BackRootOrder();
}
public int Count()
{
return Count(Root);
}
//计算节点数
public int Count(Node<T> node)
{
if (node == null) return 0;
return Count(node.Left) + Count(node.Right) + 1;
}
public int Height()
{
return Height(Root);
}
//2、计算树的高度(后序遍历)
public int Height(Node<T> node)
{
int a, b;
if (node == null) return 0;
a = Height(node.Left);
b = Height(node.Right);
if (a > b) return a + 1; else return b + 1;
}
/*二叉树遍历的应用*/
//1、计算叶子节点的个数(先序遍历)
//度为2的节点和度为0的节点也就是叶子节点的关系是n0=n2+1;加上可以统计节点的个数所以就可以
//分别统计度为0、度为1和度为2的节点数了。
public void CountLeaf(Node<T> node, ref int count)
{
if (node != null)
{
if ((node.Left == null) && (node.Right == null))
count++;
CountLeaf(node.Left, ref count);
CountLeaf(node.Right, ref count);
}
}
/// <summary>
/// 广度优先遍历(层序遍历)
///
/// </summary>
public void LevelOrder()
{
Node<T> node = root;
Queue<Node<T>> queue = new Queue<Node<T>>();
queue.Enqueue(node);
while (queue.Count > 0)
{
node = queue.Dequeue();
node.Write();
if (node.Left != null)
{
queue.Enqueue(node.Left);
}
if (node.Right != null)
{
queue.Enqueue(node.Right);
}
}
}
public void FontOrder()
{
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = Root;
while(node!=null ||stack.Count>0)
{
node.Write();
stack.Push(node);
node = node.Left;
while(node==null&&stack.Count>0)
{
node = stack.Pop();
node = node.Right;
}
}
}
public void FontOrder1()
{
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = Root;
while (node != null || stack.Count > 0)
{
if(node!=null)
{
stack.Push(node);
node.Write();
node = node.Left;
}
else
{
node = stack.Pop();
node = node.Right;
}
}
}
public void InOrder()
{
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = Root;
while (node != null || stack.Count > 0)
{
stack.Push(node);
node = node.Left;
while (node == null && stack.Count > 0)
{
node = stack.Pop();
node.Write();
node = node.Right;
}
}
}
public void InOrder1()
{
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = Root;
while (node != null || stack.Count > 0)
{
if (node != null)
{
stack.Push(node);
node = node.Left;
}
else
{
node = stack.Pop();
node.Write();
node = node.Right;
}
}
}
public void BackOrder()
{
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = null;
Node<T> pre = null;
stack.Push(Root);
while (stack.Count > 0)
{
node = stack.Peek();
if((node.Left==null&&node.Right==null)||(pre!=null&&(pre==node.Left||pre==node.Right)))
{
node.Write();
pre = node;
stack.Pop();
}
else
{
if(node.Right!=null)
{
stack.Push(node.Right);
}
if (node.Left != null)
{
stack.Push(node.Left);
}
}
}
}
public void BackOrder1()
{
Stack<Node<T>> lstack = new Stack<Node<T>>();
Stack<Node<T>> rstack = new Stack<Node<T>>();
Node<T> node = root,right=null;
do
{
while(node!=null)
{
right = node.Right;
lstack.Push(node);
rstack.Push(right);
node = node.Left;
}
node = lstack.Pop();
right = rstack.Pop();
if(right==null)
{
node.Write();
}
else
{
lstack.Push(node);
rstack.Push(null);
}
node = right;
} while (rstack.Count > 0 || rstack.Count > 0);
}
}
/// <summary>
/// 二叉树的节点
/// </summary>
/// <typeparam name="T"></typeparam>
class Node<T> : IComparable<T> where T : IComparable<T>, IPrint
{
private T data;
public T Data
{
get { return data; }
set { data = value; }
}
private Node<T> left;
public Node<T> Left
{
get { return left; }
set { left = value; }
}
private Node<T> right;
public Node<T> Right
{
get { return right; }
set { right = value; }
}
public Node (T data)
{
this.data = data;
}
public virtual int CompareTo(T other)
{
return this.CompareTo(other);
}
/// <summary>
/// 先序遍历(根节点-->左孩子-->右孩子)
/// </summary>
public virtual void FrontRootOrder()
{
Data.Print();
if(Left!=null)
{
Left.FrontRootOrder();
}
if(Right!=null)
{
Right.FrontRootOrder();
}
}
/// <summary>
/// 中序遍历(左孩子-->根节点-->右孩子)
/// </summary>
public virtual void InRootOrder()
{
if (Left != null)
{
Left.InRootOrder();
}
Data.Print();
if (Right != null)
{
Right.InRootOrder();
}
}
/// <summary>
/// 后序遍历(左孩子-->右孩子-->根节点)
/// </summary>
public virtual void BackRootOrder()
{
if (Left != null)
{
Left.BackRootOrder();
}
if (Right != null)
{
Right.BackRootOrder();
}
Data.Print();
}
public void Write()
{
Data.Write();
}
public string ToString()
{
return Data.ToString();
}
}
/// <summary>
/// 二叉树节点的数据元素
/// </summary>
class DataElement : IComparable<DataElement>, IPrint
{
private string data;
public string Data
{
get { return data; }
set { data = value; }
}
public DataElement(string data)
{
this.data = data;
}
public int CompareTo(DataElement element)
{
return this.Data.CompareTo(element.Data);
}
public void Print()
{
Console.Write(data+",");
}
public void Write()
{
Console.Write(data+",");
}
public string ToString()
{
return data;
}
}
}
测试的两个二叉树:
测试代码
/*
* author:codingriver
* 20181016 21:46
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TreeTest
{
class Program
{
static void Main(string[] args)
{
int[] array1 = new int[] { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
TestTree(array1);
Console.WriteLine("\n\n***********************************************\n\n");
int[] array2 = new int[] { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };
TestTree(array2);
}
static void TestTree(int[] arr)
{
Tree<DataElement> tree = CreateTree(arr);
tree.FrontRootOrder();
Console.WriteLine("\n============================");
tree.InRootOrder();
Console.WriteLine("\n============================");
tree.BackRootOrder();
Console.WriteLine("\n============================");
tree.LevelOrder();
Console.WriteLine("\n============================");
Console.WriteLine("\n==========非递归遍历==================");
Console.WriteLine("\n============前序================");
tree.FontOrder();
Console.WriteLine("\n");
tree.FontOrder1();
Console.WriteLine("\n============中序================");
tree.InOrder();
Console.WriteLine("\n");
tree.InOrder1();
Console.WriteLine("\n============后序================");
tree.BackOrder();
Console.WriteLine("\n");
tree.BackOrder1();
}
/// <summary>
/// 创建二叉树
/// </summary>
static Tree<DataElement> CreateTree(int[] arr)
{
int len = arr.Length;
Func<string, Node<DataElement>> createNode = (data) =>
{
var node = new Node<DataElement>(new DataElement(data));
return node;
};
int index = 0;
Func<Node<DataElement>> createTree = null;
createTree = () =>
{
Node<DataElement> node = null;
if (index < len && arr[index] != '#')
{
node = createNode(arr[index].ToString());
++index;
node.Left = createTree();
++index;
node.Right = createTree();
}
return node;
};
Tree<DataElement> tree = new Tree<DataElement>();
tree.Root = createTree();
return tree;
}
}
}
测试结果:
这篇文章整理的不够细致,后面补充吧
参考文章:
二叉树的递归与非递归实现
C#二叉树的实现