在C语言中我们实现先序遍历树的非递归算法往往是这样的:
void prev (NODE *root)
{ NODE *p, *node[MAX];
int top=0; p=root;
do
{ while( p!=NULL)
{printf(“%d,”, root->data) ;
node[top]=p;top++;
p=p->lch;
}
if (top>0)
{top - -; p=node[top]; p=p->rch; }
} while(top>0||p!=NULL);
}
其基本原理是在遍历时要保存每一个结点的信息在node数组里,以此来实现编历完左子树后实现回溯时,可通过node数组里的结点信息获取右子树的信息.
这段程序我们几乎可以完全搬到JAVA上使用,但我们可以变一变,使用JAVA的Stack类来简化操作.
Stack todo=new Stack();
todo.push(root);
while(hasNext())
{
Object old=todo.pop();
if(!old.right().isEmpty()) todo.push(old.right());
if(!old.left().isEmpty()) todo.push(old.left());
return old;
}
为了方便解释,所以部分采用了伪代码,关键在于红色的两行字,要求是先让右边的入栈,再让左边入栈,这样访问
时就是先序遍历了,这种方法代码量很小,由于JVM封装了Stack的功能,所以其功能很强,其空间的分配,空间的动
态扩展,空间中数据的移动,完全由JVM搞定了.如果以上的C代码要考虑空间的一些问题话,估计代码量要比JAVA
写的多很多了.
但有个问题我们必须注意,Stack类是继承自Vector的,如果你看过JDK的源代码,你应该知道Vector本身就是由
数组写成的,也就是说真正的实现方式和上面的C代码是没有什么区别的.我常常听到一些人说:JAVA程序员不需要
关注数据结构,而应关注架构,模式.这其实是不对的,如果你在一个程序中不计成本的使用Stack等数据结构,完全
不考虑它的使用时机和效率,看似你编的很爽,但出来的程序其效率是很低下的,特别是树这种结构,你的效率会成
几何级数的下降.
所以从某种角度来说,JAVA程序员在数据结构前面临更大的挑战,必须理解底层数据结构的原理,在使用时需要善于组织,规划.JVM中的数据结构确实很有用,但它也带给了我们麻烦,我们要从本质上去理解它们,不要被它们华丽的外表所蒙蔽.