课后习题:
/** * 二叉树中序遍历非递归算法。 * 主要思路: * 用一个栈维护所有有左孩子的节点。 * 1、当一个节点有左孩子时,就把这个节点进栈。 * 2、然后检查这个节点的左孩子节点是不是有左孩子,如果有,则这个左孩子入栈,然后循环, * 3、如果没有,则输出此左孩子的值,然后判断此左孩子有无右孩子, * 4、有则将这右孩子做第1步。 * 5、没有,则让栈顶的元素出栈,输出此节点的值 * 6、然后判断此节点有无右孩子,有,则让这个右孩子做第1步检查。 * 7、如果没有,则用第6步检查此时栈顶的元素节点。 * 8、当栈为空时则所有节点遍历完毕。 * @param root 二叉树根节点 */ public void inBTreeN(BTreeNode root) { if(root == null) return; //用栈存储所有有左孩子的节点 SequenceStack ss = new SequenceStack(); BTreeNode tNode = root; //用于区别此次循环是检查左孩子还是检查右孩子 int k = 1; //tNode != null用于处理根元素没有左节点的情况,此时一次循环后,栈还是为空 while(tNode != null){ if(k == 1 && tNode.left != null) { //有左孩子,且此节点没有被遍历检查,则入栈 ss.push(tNode); tNode = tNode.left; //下一个检查的还是左孩子 k = 1; }else{ //如果没有左孩子,则输出此节点的值 System.out.print(tNode.value + ","); //如果右孩子不为null,则检查右孩子,但右孩子不入栈 if (tNode.right != null) { tNode = tNode.right; //下一步检查右孩子的左孩子 k = 1; } else { //如果栈为空,遍历完成 if (ss.isEmpty()) { break; } //没有右孩子,则栈出栈 tNode = (BTreeNode)ss.pop(); //输出出栈元素的节点值 System.out.print(tNode.value + ","); //判断有无右孩子,确定下一次循环的节点 if (tNode.right == null) { //如果栈空,则遍历完成 if (ss.isEmpty()) { break; } //没有右孩子,则再出一个栈,即检查前一步出栈的节点的父节点 tNode = (BTreeNode)ss.pop(); //设置只检查右孩子,因为所有栈里的节点的左孩子都已经遍历 k = 2; } else { //如果有右孩子,则检查此右孩子 tNode = tNode.right; //设置检查左孩子,每检查一个新元素,都先检查其左孩子 k = 1; } } } } }
package tree; public class BTreeNode { public Object value; public BTreeNode left; public BTreeNode right; public BTreeNode(Object obj){ this.value = obj; } public BTreeNode(Object o, BTreeNode l, BTreeNode r){ this.value = o; this.left = l; this.right = r; } }