using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BitTree
{
//TODO:列印二叉樹
class Constant
{
public static readonly string Space = " ";
}
class Program
{
static void Main(string[] args)
{
//" "表示葉子結點
string preorder = "ABC DE G F ";
//string preorder = "ABDH I EJ K CFL G ";
Console.WriteLine("樹結點:{0}", preorder);
BitTree bt = new BitTree(preorder);
Node root = bt.CreateBitTreePreOrder();
int width = bt.GetTreeWidth(root);
Console.WriteLine("樹寬:{0}", width);
//樹高
int depth = bt.GetTreeDepth(root);
Console.WriteLine("樹高遞迴演算法:{0}", depth);
depth = bt.GetTreeDepthNoneRecursion(root);
Console.WriteLine("樹高非遞迴演算法:{0}", depth);
//先序
Console.WriteLine("先序遞迴遍曆:");
bt.PreTraverse(root);
Console.WriteLine();
Console.WriteLine("先序非遞迴遍曆:");
bt.PreTraverseNoneRecursion(root);
Console.WriteLine();
//中序
Console.WriteLine("中序遞迴遍曆:");
bt.MidTraverse(root);
Console.WriteLine();
Console.WriteLine("中序非遞迴遍曆:");
bt.MidTraverseNoneRecursion(root);
Console.WriteLine();
//後序
Console.WriteLine("後序遞迴遍曆:");
bt.PostTraverse(root);
Console.WriteLine();
Console.WriteLine("後序非遞迴遍曆:");
bt.PostTraverseNoneRecursion(root);
Console.WriteLine();
//層次遍曆
Console.WriteLine("層次遍曆:");
bt.TopToBottomReserver(root);
Console.ReadLine();
}
}
internal class Node
{
internal Node Left { get; set; }
internal Node Right { get; set; }
internal string Value { get; set; }
}
class BitTree
{
string inputSequence;
public BitTree(string input)
{
inputSequence = input;
}
#region 先序演算法
//先序建立二叉樹
public Node CreateBitTreePreOrder()
{
return CreateBitTreePreOrder(null);
}
private Node CreateBitTreePreOrder(Node node)
{
if (string.IsNullOrEmpty(inputSequence))
{
return null;
}
string value = inputSequence.Substring(0, 1);
inputSequence = inputSequence.Substring(1);
if (string.IsNullOrEmpty(value) || value == Constant.Space)
{
return null;
}
node = new Node();
node.Value = value;
node.Left = CreateBitTreePreOrder(node.Left);
node.Right = CreateBitTreePreOrder(node.Right);
return node;
}
//先序遍曆二叉樹,遞迴
public void PreTraverse(Node node)
{
if (node != null)
{
Console.Write(node.Value);
PreTraverse(node.Left);
PreTraverse(node.Right);
}
}
//先序遍曆二叉樹,非遞迴
public void PreTraverseNoneRecursion(Node node)
{
Stack<Node> stack = new Stack<Node>();
while (node != null || stack.Count > 0)//while用的很牛
{
if (node != null)//壓棧同時訪問
{
Console.Write(node.Value);
stack.Push(node);
node = node.Left;
}
else//處理右邊
{
node = stack.Pop();
node = node.Right;
}
}
}
#endregion
#region 中序遍曆演算法
//中序不能唯一確定一顆二叉樹
//中序遍曆二叉樹,遞迴
public void MidTraverse(Node node)
{
if (node != null)
{
MidTraverse(node.Left);
Console.Write(node.Value);
MidTraverse(node.Right);
}
}
//中序遍曆二叉樹,非遞迴
public void MidTraverseNoneRecursion(Node node)
{
Stack<Node> stack = new Stack<Node>();
while (node != null || stack.Count > 0)//while用的很牛
{
if (node != null)//壓棧
{
stack.Push(node);
node = node.Left;
}
else//彈出後訪問
{
node = stack.Pop();
Console.Write(node.Value);
node = node.Right;
}
}
}
#endregion
#region 後序遍曆演算法
//後序遍曆二叉樹,遞迴
public void PostTraverse(Node node)
{
if (node != null)
{
PostTraverse(node.Left);
PostTraverse(node.Right);
Console.Write(node.Value);
}
}
//後序遍曆二叉樹,非遞迴
public void PostTraverseNoneRecursion(Node node)
{
Stack<Node> stack = new Stack<Node>();
Node lastvisit = node;//最後訪問的結點
while (node != null || stack.Count > 0)
{
if (node != null)
{
stack.Push(node);
node = node.Left;
}
else
{
Node p = stack.Peek();//取而不出
// || (p.Right == lastvisit))//若右邊為空白,或已經訪問過,則返回到父結點
if(p.Right == null || p.Right == lastvisit)
{
stack.Pop();
Console.Write(p.Value);
lastvisit = p;
}
else//非葉結點,右邊未訪問過,訪問右邊
{
node = p.Right;
}
}
}
}
#endregion
#region 層次遍曆
public void TopToBottomReserver(Node node)
{
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(node);
while (queue.Count > 0)
{
node = queue.Dequeue();
if (node != null)
{
Console.Write(node.Value);
queue.Enqueue(node.Left);
queue.Enqueue(node.Right);
}
}
}
#endregion
#region 樹高
public int GetTreeDepth(Node node)
{
if (node == null)
{
return 0;
}
else if (node.Left == null && node.Right == null)
{
return 1;
}
else
{
int ldepth = GetTreeDepth(node.Left);
int rdepth = GetTreeDepth(node.Right);
return ldepth > rdepth ? 1 + ldepth : 1 + rdepth;
}
}
//方法和遍曆一樣,用兩個int作標記
public int GetTreeDepthNoneRecursion(Node root)
{
int depth = 0;
Stack<Node> stack = new Stack<Node>();
Node lastvisit = root;//最後訪問的結點
while (root != null || stack.Count > 0)
{
if (root != null)
{
stack.Push(root);
depth = stack.Count > depth ? stack.Count : depth;
root = root.Left;
}
else
{
Node p = stack.Peek();//取而不出
if (p.Right == null || p.Right == lastvisit)
{
stack.Pop();
lastvisit = p;
}
else//非葉結點,右邊未訪問過,訪問右邊
{
root = p.Right;
}
}
}
return depth;
}
#endregion
public int GetTreeWidth(Node root)
{
if (root == null)
{
return 0;
}
else if (root.Left == null && root.Right == null)
{
return 1;
}
else
{
int lwidth = GetTreeWidth(root.Left);
int rwidth = GetTreeWidth(root.Right);
return 1 + lwidth - rwidth;
}
}
//返回結點總數
public int GetNodeCount(Node root)
{
if (root == null)
{
return 0;
}
else if (root.Left == null && root.Right == null)
{
return 1;
}
else
{
int lwidth = GetNodeCount(root.Left);
int rwidth = GetNodeCount(root.Right);
return 1 + lwidth + rwidth;
}
}
//得到指定層上所有結點
private List<Node> GetNodeListInDepth(Node root, int depthNum)
{
int treeheight = GetTreeDepth(root);
if (root == null || depthNum > treeheight)
{
return new List<Node>();
}
List<Node> sumNode = new List<Node>();
if(depthNum == 1)
{
sumNode.Add(root);
return sumNode;
}
Node node = root;
List<Node> lchilrenlist = new List<Node>();
lchilrenlist = GetNodeListInDepth(node.Left, depthNum - 1);
List<Node> rchilrenlist = new List<Node>();
rchilrenlist = GetNodeListInDepth(node.Right, depthNum - 1);
sumNode.AddRange(lchilrenlist);
sumNode.AddRange(rchilrenlist);
return sumNode;
}
}
}