非递归二叉树遍历的核心在于模拟(Stack Frame)的过程想必有人已经
晕头转向,但是有不少.NET开发人员应不会对它陌生,调用堆栈槛
调试时经常看到,而且.NET也包含StackFrame的应用类 做网站的朋
友应该是不会去接触的吧、
上图是特意截取的一个易语言程序的调用槛,当然前提的下个断点(Break Point)
在(Stack Frame)中可以看到从未知处到断点处的一个清晰客观的调用流程,每
调用一个函数调用槛基数加一,当前函数槛永远为零 上图槛函数是MessageBoxA
当然意义不大 对于写游戏CALL而言 最多起到引导作用、你还的读汇编.
调用堆栈槛与非递归二叉树遍历有什么关系呢?好的,回到正题在上文中
我有说过,非递归是模拟调用堆栈的过程,这个过程指的什么过程?指的
是递归遍历二叉树的过程,每次调用函数都会压入计算堆栈该函数执行完
后弹出计算堆栈 且对ESP / RSP做一个处理(此处可以忽略)
public static void BuildTree(BinTree root) // 先序
{
BinTree p = root;
Stack<BinTree> stack = new Stack<BinTree>();
while (stack.Count > 0 || p != null)
{
while (p != null)
{
Console.WriteLine(p.Data);
stack.Push(p);
p = p.Left;
}
if (stack.Count > 0)
{
p = stack.Pop();
p = p.Right;
}
}
}
上面的代码如何理解,由于BuildTree只有一个参数,所以定义计算堆栈
数据寄存的集合只有一个 若是两个参数需要入栈 肯定需要保存两个当
然是不是一定需要用到.NET的Stack泛型类吗 不是的你可以使用数组代
替表示 二叉树遍历在压入堆栈寄存的数据计数最大不会超过二
public void BuildTree(BinTree root)
{
BinTree p = root;
List<BinTree> s = new List<BinTree>();
while (s.Count > 0 || p != null)
{
while (p != null)
{
Console.WriteLine(p.DAT);
s.Add(p);
p = p.Left;
}
if (s.Count > 0)
{
p = s[0];
s.RemoveAt(0);
p = p.Right;
}
}
上方是一个通过.NET泛型List泛型类的实现的非递归二叉树遍历与利用
Stack泛型类的方法一致,当然如果理解非递归二叉树遍历那么至于用
什么语言或代码代替,已经不再重要
public class BinTree
{
public BinTree Left;
public BinTree Right;
public string Data;
}
public static void Main(string[] args)
{
BinTree root = new BinTree() { Data = "A" };
root.Left = new BinTree() { Data = "B", Right = new BinTree() { Data = "D" } };
root.Right = new BinTree() { Data = "C" };
BuildTree(root);
Console.ReadKey(false);
}