81,122
社区成员




public static void LaGet1(TreeModels root){//后续遍历(非递归),基于栈
TreeStack ts=new TreeStack();//这个是栈
TreeModels root1=null;//这个保存前一个遍历过得节点
while(root!=null||ts.index!=0){
while(root!=null){
ts.push(root);//栈的push操作
//System.out.println(root.getData());
root=root.getLeft();
}
if(ts.index!=0){
root=ts.pop();//退栈操作
if(root.getRight()==null||root.getRight()==root1){
System.out.print(root.getData()+" ");
root1=root;
root=null;
//System.out.println("root1: "+root1.getData());
}
else{
root=root.getRight();
}
}
}
}
一定要认真学习
void POSTORDER(binary_tree *root)
{
binary_tree *stack[MAX_STACK_SIZE];
while( root || esp != -1)
{
if(root&& !root->flag)
{
push(&esp,stack,root);
root=root->left_child;
continue;
}
if(esp == -1)
break;
//SIGN:
root = pop(&esp,stack);
if( !root->flag )
{
root->flag=1;
push(&esp,stack,root);
root=root->right_child;
}
else
{
printf("%d\n",root->data);
// goto SIGN
}
}
}
从递归版本的代码来分析如何得到这个非递归版本
后序遍历,递归
void postorder(binary_tree *root)
{
if( root)
{
postorder(root -> left_child);
postorder(root -> right_child);
printf("Node\n");
}
}
简要的分析一下这个递归函数。
函数调用的时候 把 1.访问右子树的操作
2.和访问本节点数据域的操作先放在一边
可以理解为 将这两个操作压栈。
逐步之下,直到遇到左子树为空的情况,弹出对应操作。
1
2 3
4 5 6 7
。 。。 。。 。 。 。
当前节点 压栈操作
1 访问3 输出1
2 访问5 输出2
4 访问。 输出4
。
当到达。的时候, 没有后继操作
于是弹出堆栈里的参数,以便做对应的操作。
弹出访问。 没有后继操作
弹出输出4 printf("NODE"); //这时 4的左右子树都已经访问完毕
弹出访问5 5作为一个新的节点 产生一个压栈的动作 : 访问。 输出5
当前位置。 没有操作
弹出。 没有操作
弹出输出5
这样 4和5作为2的子树, 已经访问完毕,现在可以访问2.
否则 按照如上的操作继续下去, 弹出2 又产生 将 访问5和输出2的操作 压栈的东西 ,必然进入死循环。
于是想要设置一个标志位 当2的左右子树的访问完毕的时候, 标记一下 这时候弹出 输出2的操作。
以上压栈时的参数全为 指针 写成操作纯粹为了好理解。
大概可以这样。
当到达一个节点的时候, 将当前节点指针压栈。
当该节点的左子树访问完毕以后,该节点的节点指针必然出栈,但是该出栈动作只是为了寻找它的右子树。
所以还要将该节点指针重新进栈
关键就在这里, 这一进一出的操作,表示已经访问了这个节点的左右子树,下次在碰到这个节点的时候
弹出它 并且对它进行printf()操作。
为了便于标示这个动作, 我们给这个指针设置一个标记,或者说给这个节点设置一个标记。
typedef struct BINARY_TREE{
int flag;
BINARY_TREE *lp;
BINARY_TREE *rp;
int data;
}binary_tree;
结构中的flag用于标记 该节点的左右子树已成功访问。
对于没访问的flag默认为0;
访问成功的 flag设置为1;
这样就解决了死循环的问题。
[quote=引用 39 楼 h2plus0 的回复:] 最主要的想法是把一个节点展开, 但放到stack中的时候需要记住这个节点有没有展开过import java.util.Stack; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; /** * post order access tree * http://www.devbeacon.com */ public class PostOrderAccessTree { static class StkData { public StkData(TreeNode node) { this.node = node; expanded = false; } TreeNode node; boolean expanded; } public static void post(TreeNode root) { if(root==null) return; Stack<StkData> stk = new Stack<StkData>(); StkData d = new StkData(root); stk.push(d); while(!stk.empty()) { d = stk.peek(); // not pop !! if(d.expanded) { System.out.println(d.node); stk.pop(); } else { d.expanded = true; for(int i=d.node.getChildCount()-1;i>=0;i--) { StkData t = new StkData(d.node.getChildAt(i)); stk.push(t); } } } } public static void main(String[] args) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("a"); DefaultMutableTreeNode b = new DefaultMutableTreeNode("b"); DefaultMutableTreeNode c = new DefaultMutableTreeNode("c"); DefaultMutableTreeNode d = new DefaultMutableTreeNode("d"); DefaultMutableTreeNode e = new DefaultMutableTreeNode("e"); DefaultMutableTreeNode f = new DefaultMutableTreeNode("f"); DefaultMutableTreeNode g = new DefaultMutableTreeNode("g"); DefaultMutableTreeNode h = new DefaultMutableTreeNode("h"); root.add(b); root.add(c); b.add(d); b.add(e); c.add(f); c.add(g); e.add(h); post(root); } }