先定义树节点类(TreeNode)和二叉树类(BinaryTree)
public class TreeNode<T>
{
public T Data { get; set;}
public TreeNode<T> Parent { get;protected set; }
protected virtual int Deepth
{
get
{
if(Parent!=null)
{
return Parent.Deepth + 1;
}
return 0;
}
}
}
class BinaryTree<T> : TreeNode<T>
{
private BinaryTree<T> _leftTree;
private BinaryTree<T> _rightTree;
public BinaryTree<T> LeftTree
{
get { return _leftTree; }
set
{
if (_leftTree != null)
_leftTree.Parent = null;
_leftTree = value;
if (_leftTree != null)
_leftTree.Parent = this;
}
}
public BinaryTree<T> RightTree
get { return _rightTree; }
set
{
if (_rightTree != null)
_rightTree.Parent = null;
_rightTree = value;
if (_rightTree != null)
_rightTree.Parent = this;
}
}
}
二叉树遍历分为:
- 前序遍历(DLR):访问根节点->前序遍历左子树->前序遍历右子树;
- 中序遍历(LDR):中序遍历左子树->访问根节点->中序遍历右子树;
- 后序遍历(LRD):后序遍历左子树->后序遍历右子树->访问根节点;
- 按层遍历(Level Travel):先访问所有兄弟节点,再访问所有兄弟节点的所有直接子节点.
DLR递归实现
public static T[] DLRTravel<T>(BinaryTree<T> tree)
{
List<T> result = new List<T>();
result.Add(tree.Data);
if (tree.LeftTree != null)
result.AddRange(DLRTravel(tree.LeftTree));
if (tree.RightTree != null)
result.AddRange(DLRTravel(tree.RightTree));
return result.ToArray();
}
DLR非递归实现
public static T[] DLRTravelNoRecursion<T>(BinaryTree<T> tree)
{
if (tree == null)
return null;
var result = new List<T>();
Stack<BinaryTree<T>> stack = new Stack<BinaryTree<T>>();
stack.Push(tree);
while (stack.Count > 0)
{
BinaryTree<T> node = stack.Pop();
result.Add(node.Data);
if (node.RightTree != null)
stack.Push(node.RightTree);
if (node.LeftTree != null)
stack.Push(node.LeftTree);
}
return result.ToArray();
}
LRD递归实现
public static T[] LRDTravel<T>(BinaryTree<T> tree)
{
var result = new List<T>();
if (tree.LeftTree != null)
result.AddRange(LRDTravel(tree.LeftTree));
if (tree.RightTree != null)
result.AddRange(LRDTravel(tree.RightTree));
result.Add(tree.Data);
return result.ToArray();
}
LRD非递归实现
考虑到LRD实际上就是倒序的DRL,所以我们可以把DLR的非递归实现稍微改下执行顺序,最后把结果反转就行了.
注意:1、这里用Stack存储结果;2、左子树和右子树入栈顺序与DLR不同。
public static T[] LRDTravelNoRecursion<T>(BinaryTree<T> tree)
{
if (tree == null)
return null;
var result = new Stack<T>();
Stack<BinaryTree<T>> stack = new Stack<BinaryTree<T>>();
stack.Push(tree);
while (stack.Count > 0 )
{
BinaryTree<T> node = stack.Pop();
result.Push(node.Data);
if (node.LeftTree != null)
stack.Push(node.LeftTree);
if (node.RightTree != null)
stack.Push(node.RightTree);
}
return result.ToArray();
}
LDR递归实现
public static T[] LDRTravel<T>(BinaryTree<T> tree)
{
List<T> result = new List<T>();
if (tree.LeftTree != null)
result.AddRange(LDRTravel(tree.LeftTree));
result.Add(tree.Data);
if (tree.RightTree != null)
result.AddRange(LDRTravel(tree.RightTree));
return result.ToArray();
}
LDR非递归实现稍显麻烦
public static T[] LDRTravelNoRecursion<T>(BinaryTree<T> tree)
{
if (tree == null)
return null;
var result = new List<T>();
Stack<BinaryTree<T>> stack = new Stack<BinaryTree<T>>();
BinaryTree<T> node = tree;
while (stack.Count > 0||node!=null)
{
while (node != null)
{
stack.Push(node);
if (node.LeftTree != null)
node = node.LeftTree;
else node = null;
}
node = stack.Pop();
result.Add(node.Data);
if (node.RightTree != null)
node = node.RightTree;
else node = null;
}
return result.ToArray();
}
按层遍历
public static T[] LevelTravel<T>(BinaryTree<T> tree)
{
var queue = new Queue<BinaryTree<T>>();
queue.Enqueue(tree);
var result = new List<T>();
LevelTravelImpl(queue, result);
return result.ToArray();
}
/// <summary>
/// 二叉树按层遍历递归体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="queue"></param>
/// <param name="result"></param>
private static void LevelTravelImpl<T>(Queue<BinaryTree<T>> queue, List<T> result)
{
if (queue == null || queue.Count == 0)
return;
var tree = queue.Dequeue();
if (tree.LeftTree != null)
{
queue.Enqueue(tree.LeftTree);
result.Add(tree.LeftTree.Data);
}
if (tree.RightTree != null)
{
queue.Enqueue(tree.RightTree);
result.Add(tree.RightTree.Data);
}
LevelTravelImpl(queue, result);
}