标签:amp input add htm str console abd 输出 net
遍历二叉树有前序,中序,后序三大方法算。对于二叉树的三种不同的遍历方式,用递归的方法很容易写出实现代码,对于非递归的遍历算法使用数据结构堆栈作为工具代替递归以节省时空开销,在经过节点是先将其压入栈,要到他第几次从栈中弹出是才访问它,对于前序来说,是一次,对于中序来说是两次,对于后序则是三次。下面介绍下二叉树的几种遍历算法,包括递归和非递归的实现。
关于二叉树遍历方式的规则,可前往这里,本篇主要是对算法的陈列。
首先,我们先建个二叉树结构
我们建立如下图所示的二叉树
然后,我们创建树,和遍历的结构,采用策略模式,让客户端调用
//创建数的结构
public class Tree
{
public string Data { get; set; }
public Tree L_Tree { get; set; }
public Tree R_Tree { get; set; }
public Tree(string data)
{
this.Data = data;
this.L_Tree = null;
this.R_Tree = null;
}
public Tree(string data,Tree l,Tree r)
{
this.Data = data;
this.L_Tree = l;
this.R_Tree = r;
}
}
//定义一个管理树的类,
public class TreeManager
{
public TreeManager()
{
this.BuildTree();
}
//树的根节点
private Tree root_Tree;
private void BuildTree()
{
Tree g = new Tree("G");
Tree d = new Tree("D", g, null);
Tree h = new Tree("H");
Tree e = new Tree("E", null, h);
Tree b = new Tree("B", d, e);
Tree f = new Tree("F");
Tree c = new Tree("C", null, f);
Tree a = new Tree("A", b, c);
root_Tree = a;
}
//通过递归遍历
public void outputTree_Recursion(ITreeShow fs)
{
fs.show_Tree_Recursion(this.root_Tree);
}
//通过递归遍历
public void show_Tree_NonRecursion(ITreeShow fs)
{
fs.show_Tree_NonRecursion(this.root_Tree);
}
}
//定义了一个接口类 (作为先序,中序,后序等方式遍历的抽象)
public interface ITreeShow
{
void show_Tree_NonRecursion(Tree t);
void show_Tree_Recursion(Tree t);
}
准备工作做好以后,现在开始各种遍历算法的实现
先序是根节点,左子树,右子数
//先序遍历
public class First_Read_Show : ITreeShow
{
//非递归-先序
public void show_Tree_NonRecursion(Tree t)
{
Stack<Tree> tree_stack = new Stack<Tree>();
while (t != null || tree_stack.Count > 0)
{
if (t != null)
{
Console.Write(t.Data+",");
tree_stack.Push(t);
t = t.L_Tree;
}
else
{
var item = tree_stack.Pop();
t = item.R_Tree;
}
}
}
//递归-先序
public void show_Tree_Recursion(Tree t)
{
if (t == null)
{
return;
}
Console.Write(t.Data + ",");
show_Tree_Recursion(t.L_Tree);
show_Tree_Recursion(t.R_Tree);
}
}
中序是先左子树,再根节点,再右子树
public class Middle_Read_Show : ITreeShow
{
public void show_Tree_NonRecursion(Tree t)
{
Stack<Tree> stack_tree = new Stack<Tree>();
while (t != null || stack_tree.Count > 0)
{
if (t != null)
{
stack_tree.Push(t);
t = t.L_Tree;
}
else
{
var item = stack_tree.Pop();
Console.Write(item.Data+",");
t = item.R_Tree;
}
}
}
//递归-后序
public void show_Tree_Recursion(Tree t)
{
if (t == null)
{
return;
}
show_Tree_Recursion(t.L_Tree);
Console.Write(t.Data + ",");
show_Tree_Recursion(t.R_Tree);
}
}
后序是先左子树,再右子树,再根节点
//后序遍历
public class Last_Read_Show : ITreeShow
{
//非递归-后序
public void show_Tree_NonRecursion(Tree t)
{
Stack<Tree> stack_tree = new Stack<Tree>();
HashSet<Tree> visited = new HashSet<Tree>();
while (t != null || stack_tree.Count > 0)
{
if (t != null)
{
stack_tree.Push(t);
t = t.L_Tree;
}
else
{
var item=stack_tree.Peek();
if (item.R_Tree != null && !visited.Contains(item.R_Tree))
{
t = item.R_Tree;
}
else {
Console.Write(item.Data+",");
visited.Add(item);
stack_tree.Pop();
}
}
}
}
//递归-后序
public void show_Tree_Recursion(Tree t)
{
if (t == null)
{
return;
}
show_Tree_Recursion(t.L_Tree);
show_Tree_Recursion(t.R_Tree);
Console.Write(t.Data + ",");
}
层序遍历就是按照层次由左向右输出
public class Layer_Read_Show : ITreeShow
{
public void show_Tree_NonRecursion(Tree t)
{
Queue<Tree> queue_tree = new Queue<Tree>();
if (t != null)
{
queue_tree.Enqueue(t);
while (queue_tree.Count > 0)
{
var item = queue_tree.Dequeue();
Console.Write(item.Data + ",");
if (item.L_Tree != null)
{
queue_tree.Enqueue(item.L_Tree);
}
if (item.R_Tree != null)
{
queue_tree.Enqueue(item.R_Tree);
}
}
}
}
public void show_Tree_Recursion(Tree t)
{
}
}
static void Main(string[] args)
{
TreeManager tree = new TreeManager();
//先序-递归
Console.WriteLine("先序-递归:");
tree.outputTree_Recursion(new First_Read_Show());
//先序-非递归
Console.WriteLine();
Console.WriteLine("先序-非递归:");
tree.show_Tree_NonRecursion(new First_Read_Show());
//中序-递归
Console.WriteLine();
Console.WriteLine("中序-递归:");
tree.outputTree_Recursion(new Middle_Read_Show());
//中序-非递归
Console.WriteLine();
Console.WriteLine("中序-非递归:");
tree.show_Tree_NonRecursion(new Middle_Read_Show());
//后序-递归
Console.WriteLine();
Console.WriteLine("后序-递归:");
tree.outputTree_Recursion(new Last_Read_Show());
//后序-非递归
Console.WriteLine();
Console.WriteLine("后序-非递归:");
tree.show_Tree_NonRecursion(new Last_Read_Show());
//层次遍历
Console.WriteLine();
Console.WriteLine("层次遍历:");
tree.show_Tree_NonRecursion(new Layer_Read_Show());
Console.ReadKey();
}
二叉树的遍历算法包括递归和非递归两种,递归比较简单,先叙述下非递归算法的实现
为了便于理解,这里以下图的二叉树为例,分析二叉树的三种遍历方式的实现过程。
根据先序遍历的顺序,先访问根节点,再访问左子树,后访问右子树,而对于每个子树来说,又按照同样的访问顺序进行遍历,上图的先序遍历顺序为:ABDECF。非递归的实现思路如下:
对于任一节点P,根据中序遍历的顺序,先访问左子树,再访问根节点,后访问右子树,而对于每个子树来说,又按照同样的访问顺序进行遍历,上图的中序遍历顺序为:DBEAFC。非递归的实现思路如下:
对于任一节点P,根据后序遍历的顺序,先访问左子树,再访问右子树,后访问根节点,而对于每个子树来说,又按照同样的访问顺序进行遍历,上图的后序遍历顺序为:DEBFCA。后序遍历的非递归的实现相对来说要难一些,要保证根节点在左子树和右子树被访问后才能访问,思路如下:
对于任一节点P,完整代码下载地址:点这里
标签:amp input add htm str console abd 输出 net
原文地址:http://www.cnblogs.com/wwkk/p/7221734.html