您的位置:首页 > 其它

二叉树前中后序递归/非递归遍历以及按层遍历

2018-03-05 20:54 141 查看
先定义树节点类(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;
}
}
}
二叉树遍历分为:
前序遍历[b](DLR):访问根节点->前序遍历左子树->前序遍历右子树;[/b]
中序遍历(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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: