`
daojin
  • 浏览: 690252 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

非递归遍历二叉树的方法

 
阅读更多

package interview;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * None recursive pre-order, post-order and in-order. In order to back trace,
 * the main idea here is using a Node that point to the last popped Node.
 * 
 * 
 * 
 * The last popped Node must have some kind of relationship with the current top
 * Node in the stack.
 * 
 * 1. last Node is the child of top Node; 2. last Node is the siblings of the
 * top Node; 3. last Node is the parent of the top Node;
 * 
 * <p>
 * A. For preOrder scenario, last Node is the parent of the top Node. We can
 * also use the same thinking that we never pop-up the parent unless the 2
 * children are visited. But here we do not need that, I found that the parent
 * node is useless because when comes from right node, we certainly need to go
 * back to the up level.
 * </p>
 * 
 * <p>
 * B. For inOrder and post scenario, the last Node is the child or sibling of
 * the top Node. We never pop-up the parent unless the 2 children are visited
 * </p>
 * 
 * @author wa505
 *
 */
public class BinaryTreeNoneRecursive {

	public static void main(String[] args) {

		Stack<Node> stack = new Stack<>();
		int i = 0;
		Node root = new Node();
		root.value = i++;
		stack.push(root);
		while (!stack.isEmpty() && i <= 6) {
			List<Node> tempList = new ArrayList<>();
			while (!stack.isEmpty()) {
				Node top = stack.pop();
				Node left = addLeft(top, i++);
				Node right = addRight(top, i++);
				tempList.add(right);
				tempList.add(left);
			}
			for (Node node : tempList) {
				stack.push(node);
			}
		}

		BinaryTreeNoneRecursive bTree = new BinaryTreeNoneRecursive();
		List<Node> preList = bTree.preOrder(root);
		System.out.println("================preList");
		for (Node node : preList) {
			System.out.println(node.value);
		}

		System.out.println("================inList");
		List<Node> inList = bTree.inOrder(root);
		for (Node node : inList) {
			System.out.println(node.value);
		}

		System.out.println("================inList2");
		List<Node> inList2 = bTree.inOrder2(root);
		for (Node node : inList2) {
			System.out.println(node.value);
		}

		System.out.println("================postList");
		List<Node> postList = bTree.postOrder(root);
		for (Node node : postList) {
			System.out.println(node.value);
		}

	}

	static Node addLeft(Node node, int value) {
		Node child = new Node();
		child.value = value;
		node.left = child;
		return child;
	}

	static Node addRight(Node node, int value) {
		Node child = new Node();
		child.value = value;
		node.right = child;
		return child;
	}

	static class Node {
		int value;
		Node left;
		Node right;
	}

	List<Node> preOrder(Node root) {
		List<Node> result = new ArrayList<>();
		Stack<Node> stack = new Stack<>();
		stack.push(root);
		while (stack.size() > 0) {
			Node node = stack.pop();
			if (node != null) {
				result.add(node);
				stack.push(node.right);
				stack.push(node.left);
			}
		}
		return result;
	}

	/**
	 * 【数据结构】《清华大学版》算法
	 * 
	 * @param root
	 * @return
	 */
	List<Node> inOrder2(Node root) {

		List<Node> result = new ArrayList<>();

		Stack<Node> stack = new Stack<>();

		/**
		 * p 表示待要向左走到尽头的 新节点。
		 */
		Node p = root;

		while (!stack.isEmpty() || p != null) {

			//向左走到没有左节点
			while (p != null) {

				stack.push(p);

				p = p.left;

			}

			//访问节点
			if (!stack.isEmpty()) {
				
				Node top = stack.peek();

				result.add(top);

				stack.pop();
				
				//得到待要走到尽头的新节点。
				p = top.right;
			}

		}
		return result;
	}

	List<Node> inOrder(Node root) {
		List<Node> result = new ArrayList<>();
		Stack<Node> stack = new Stack<>();
		stack.push(root);
		Node lastNode = null;
		while (stack.size() > 0) {
			Node top = stack.peek();
			if (top.right == lastNode && lastNode != null) {
				stack.pop();
				lastNode = top;
			} else if (top.left == lastNode && lastNode != null) {
				result.add(top);
				if (top.right == null) {
					stack.pop();
					lastNode = top;
				} else {
					stack.push(top.right);
				}
			} else if (top.left != null) {
				stack.push(top.left);
			} else if (top.right != null) {
				stack.push(top.right);
			} else {
				result.add(stack.pop());
				lastNode = top;
			}
		}
		return result;
	}

	List<Node> postOrder(Node root) {
		List<Node> result = new ArrayList<>();
		Stack<Node> stack = new Stack<>();
		stack.push(root);
		Node lastNode = null;
		while (stack.size() > 0) {
			Node top = stack.peek();
			if (top.right == lastNode && lastNode != null) {
				stack.pop();
				lastNode = top;
				result.add(top);
			} else if (top.left == lastNode && lastNode != null) {
				if (top.right == null) {
					stack.pop();
					lastNode = top;
					result.add(top);
				} else {
					stack.push(top.right);
				}
			} else if (top.left != null) {
				stack.push(top.left);
			} else if (top.right != null) {
				stack.push(top.right);
			} else {
				stack.pop();
				lastNode = top;
				result.add(top);
			}
		}
		return result;
	}
}


分享到:
评论

相关推荐

    数据结构-非递归遍历二叉树

    非递归遍历二叉树是一种不依赖递归函数来访问树的所有节点的方法,它通常通过栈或队列等数据结构来实现。下面我们将详细探讨非递归遍历二叉树的先序、中序和后序策略。 先序遍历是二叉树遍历的一种方法,其顺序为:...

    二叉树的非递归遍历

    二叉树的非递归遍历,使用C++实现二叉树的非递归遍历,对正在学习算法的同学应该挺有帮助的

    c语言递归遍历二叉树

    递归遍历二叉树、c语言以及数据结构均要用到,我还会上传非递归的··

    非递归遍历二叉树 C语言实现 源码

    ### 非递归遍历二叉树:C语言实现详解 #### 一、引言 在计算机科学中,二叉树是一种常见的数据结构,它由一个根节点以及最多两个子树构成,这两个子树各自又可以是二叉树。二叉树的遍历是其操作中最基本且频繁的...

    二叉树的操作--递归非递归遍历、结点个数、树深度

    先序非递归遍历二叉树: a b c 中序递归遍历二叉树: b a c 中序非递归遍历二叉树: b a c 后序递归遍历二叉树: b c a 后序非递归遍历二叉树: b c a 二叉树的深度是2 二叉树的结点个数是3 Press any key to ...

    二叉树的递归遍历、非递归遍历和层次遍历

    二叉树的递归遍历、非递归遍历和层次遍历

    非递归遍历二叉树

    用c语言编写的非递归遍历二叉树算法及实现 可供参考学习

    二叉树的建立、递归遍历及非递归遍历

    中根顺序递归建立二叉树,递归及非递归遍历二叉树。C++面向过程实现

    非递归遍历完全二叉树 & 递归遍历完全二叉树

    非递归遍历则需要更复杂的逻辑,但可以避免栈溢出问题,并在某些情况下提供更好的性能。 在`Tree.cpp`文件中,可能包含了上述各种遍历方法的C++实现。通过阅读和理解这些代码,你可以学习如何在实际编程中处理完全...

    c语言 二叉树应用:创建、递归非递归遍历、计算结点、分支、交换子树

    非递归先序遍历二叉树: 非递归中序遍历二叉树: 非递归后序遍历二叉树: 非递归中序遍历二叉树(算法2): 层次遍历二叉树: 递归计算单分支结点: 递归计算双分支结点: 递归计算叶子数: 二叉数的深度:...

    C++代码实现先、中、后递归与非递归遍历二叉树

    用先序的方式创建二叉树,“#”代表空,然后自动输出递归与非递归的先中后三种顺序遍历二叉树

    中序遍历二叉树非递归算法

    在IT领域,尤其是在数据结构与算法的学习中,中序遍历二叉树的非递归算法是一个关键且实用的知识点。通常,我们首先通过递归来实现二叉树的遍历,但递归方法可能因深度过大导致栈溢出,因此掌握非递归版本的遍历算法...

    二叉树递归和非递归遍历实验报告(含源码)

    本实验报告将深入探讨二叉树的递归和非递归遍历方法,并附带源代码实现,旨在帮助读者理解这两种遍历策略及其应用场景。 一、二叉树遍历 二叉树遍历主要有三种方法:前序遍历、中序遍历和后序遍历。它们是遍历...

    二叉树递归和非递归遍历以及层次构建节点数为n的二叉树

    二种非递归实现 二叉树中序遍历: 递归实现 非递归实现 二叉树后序遍历: 递归实现 非递归实现 二叉树层次遍历 二叉树层次创建,创建方法遵循卡特兰数 http://write.blog.csdn.net/postedit/17380455

    关于二叉树前序和后序的非递归遍历算法.rar

    在"关于二叉树前序和后序的非递归遍历算法.pdf"这份文档中,可能详细介绍了这两种遍历方法的实现步骤、伪代码以及可能遇到的问题和解决方案。读者可以通过阅读这份文档深入理解非递归遍历算法,并通过实践来提升自己...

    更简单的非递归遍历二叉树的方法

    更简单的非递归遍历二叉树的方法 思路非常简洁,多看多思考

    数据结构非递归遍历二叉树

    非递归遍历二叉树是一种不依赖递归函数来访问树中所有节点的方法,这在处理大型或深度较大的树时特别有用,因为它避免了调用栈溢出的风险。 二叉树的主要遍历方法有三种:前序遍历、中序遍历和后序遍历。在递归方式...

    二叉树递归与非递归遍历

    二叉树遍历是计算机科学中处理二叉树数据结构的一种基本操作,它涉及到访问二叉树中的每个节点。在二叉树中,每个节点最多有两个子节点...理解并熟练掌握递归和非递归遍历方法对任何IT专业人员来说都是非常重要的技能。

    数据结构二叉树遍历递归,非递归

    理解递归遍历后,非递归遍历的关键在于使用额外的数据结构(如栈或队列)来跟踪当前的遍历状态。非递归遍历的优势在于它避免了函数调用栈的深度限制,对于非常深的树,递归可能会导致栈溢出。 在实际编程中,根据...

Global site tag (gtag.js) - Google Analytics