二叉树遍历的非递归Java实现

来源:互联网 发布:如何看待网络成瘾行为 编辑:程序博客网 时间:2024/06/08 07:00

    关于二叉树的3种遍历方式原理,原文博主已经详细介绍了,这里只附上非递归形式的Java代码。

    原文地址:http://blog.csdn.net/pi9nc/article/details/13008511/

    关于二叉树,请参考另一篇文章:http://blog.csdn.net/ifleetingtime/article/details/78836638

/** * 非递归,遍历整个树 * 中序遍历 * 顺序: 左子节点 -> 父节点 -> 右子节点 */public void in_traverse() {if (root == null)return ;Stack<Node> stack = new Stack<>(); // 暂存节点Node currentNode = root;while (true) {if (currentNode.getLeftNode() != null) {stack.push(currentNode);   // 将当前节点 A 入栈currentNode = currentNode.getLeftNode(); // 如果当前节点有左子节点,继续执行左子节点}else {System.out.print(currentNode.getData() + " ");currentNode = currentNode.getRightNode(); // 将此节点A 从栈中拿出来,获取它的右子节点while (currentNode==null && !stack.isEmpty()) {currentNode = stack.pop(); // A的右子节点为空,继续出栈,找父节点System.out.print(currentNode.getData() + " "); // 找到父节点之后,先打印父节点,再去找其右节点currentNode = currentNode.getRightNode();}if (currentNode == null)    // 如果栈空了,没有找到右子节点,则循环完成break;                  // else  continue        // 否则 将右子节点作为当前节点继续遍历}}}/** * 非递归,遍历整个树 * 前序遍历 * 顺序: 父节点 -> 左子节点 -> 右子节点 */public void pre_traverse() {if (root == null)return ;Stack<Node> stack = new Stack<>(); // 暂存节点Node currentNode = root;while (true) {System.out.print(currentNode.getData() + " ");stack.push(currentNode);   // 将当前节点 A 入栈if (currentNode.getLeftNode() != null) {currentNode = currentNode.getLeftNode(); // 如果当前节点有左子节点,继续执行左子节点}else {currentNode = stack.pop().getRightNode(); // 将此节点A 从栈中拿出来,上面刚放进去,获取它的右子节点while (currentNode==null && !stack.isEmpty()) {currentNode = stack.pop().getRightNode(); // A的右子节点为空,继续出栈,找父节点的右子节点, 找到第一个存在的右子节点}if (currentNode == null)    // 如果栈空了,没有找到右子节点,则循环完成break;                  // else  continue        // 否则 将右子节点作为当前节点继续遍历}}}/** * 非递归,遍历整个树 * 后序遍历 * 顺序: 左子节点 -> 右子节点  -> 父节点 */public void post_traverse() {if (root == null)return ;Stack<Node> stack = new Stack<>(); // 暂存节点Node currentNode = root;Node lastNode = null;  // 暂存上一个数据的节点stack.push(currentNode); // 先将根节点入栈while (!stack.isEmpty()) {currentNode = stack.peek(); // 获取栈顶元素,不要移除它,不移除的原因: 子节点可能没遍历到,要把子节点压在这个节点上面,先执行子节点// 如果此时的元素没有左右节点,或者左右节点已经被遍历过了,因为是自下向上遍历,子节点永远是父节点之前紧挨着遍历到的,所以我们用一个lastNode变量保存上一个遍历到的节点if ( (currentNode.getLeftNode()==null && currentNode.getRightNode()==null) || ( lastNode!=null && (currentNode.getLeftNode()==lastNode || currentNode.getRightNode()==lastNode) )   ){System.out.print(currentNode.getData() + " ");lastNode = currentNode;stack.pop(); // 这个节点自身,和子节点都遍历到了,移除,从父节点开始重新遍历}else {// 先入栈右子节点,再入栈左子节点, 这样从栈中取数据时,先执行左子节点,再执行右子节点if (currentNode.getRightNode() != null) {stack.push(currentNode.getRightNode());}if (currentNode.getLeftNode() != null) {stack.push(currentNode.getLeftNode());}}}}



原创粉丝点击