二叉树,先-中-后,遍历

建议大家在小本本上,模拟一下,遍历路径,才能更好的理解代码

代码如下:

package class_04;

import java.util.Stack;

public class Code_01_PreInPosTraversal {

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

		public Node(int data) {
			this.value = data;
		}
	}

	public static void preOrderRecur(Node head) {   // 递归版-先序遍历
		if (head == null) {
			return;
		}
		System.out.print(head.value + " ");
		preOrderRecur(head.left);
		preOrderRecur(head.right);
	}

	public static void inOrderRecur(Node head) {     // 递归版-中序遍历
		if (head == null) {
			return;
		}
		inOrderRecur(head.left);
		System.out.print(head.value + " ");
		inOrderRecur(head.right);
	}

	public static void posOrderRecur(Node head) {    // 递归版-后序遍历
		if (head == null) {
			return;
		}
		posOrderRecur(head.left);
		posOrderRecur(head.right);
		System.out.print(head.value + " ");
	}

	/*
	 * 非递归版,先序遍历
	 * 为什么要利用栈,原因:因为二叉树是一个从上到下的过程,而栈可以返回上去。
	 * 思路:首先把根节点压入,先压右,再压左,这样出栈顺序就是 先左后右,弹出一个,就打印一个。
	 * 
	 * */
	public static void preOrderUnRecur(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.add(head);                // 首先把根节点压入栈中
			while (!stack.isEmpty()) {
				head = stack.pop();  
				System.out.print(head.value + " ");
				if (head.right != null) {   // 有右压右孩子
					stack.push(head.right);
				}
				if (head.left != null) {    // 有左压左孩子
					stack.push(head.left);
				}
			}
		}
		System.out.println();
	}

	/*
	 * 非递归版,中序遍历
	 * 思路:先把当前结点的左边界压入栈中,如果当前结点为空,从栈中弹出一个打印,当前结点网右走,
	 * 否则,继续把左边界压入栈中
	 * 
	 * */
	public static void inOrderUnRecur(Node head) {
		System.out.print("in-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			while (!stack.isEmpty() || head != null) {
				if (head != null) {      // 把当前结点,左边界全部压入栈中
					stack.push(head);
					head = head.left;
				} else {            
					head = stack.pop();  // 弹出打印结点
					System.out.print(head.value + " ");
					head = head.right;   // head向右移动
				}
			}
		}
		System.out.println();
	}

	
	/* 非递归版,后序遍历
	 * 思路:后序遍历顺序是:左右中,那么反过来,中右左,便是先序遍历的思路了。
	 * 只不过用一个辅助栈,逆序打印出来
	 * */
	public static void posOrderUnRecur1(Node head) {
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();  // 辅助栈
			s1.push(head);
			while (!s1.isEmpty()) {
				head = s1.pop();
				s2.push(head);      // 压入辅助栈
				if (head.left != null) {  // 有左先压左
					s1.push(head.left);
				}
				if (head.right != null) { // 有右就压右
					s1.push(head.right);
				}
			}
			while (!s2.isEmpty()) {
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

	public static void posOrderUnRecur2(Node h) {
		System.out.print("pos-order: ");
		if (h != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.push(h);
			Node c = null;
			while (!stack.isEmpty()) {
				c = stack.peek();
				if (c.left != null && h != c.left && h != c.right) {
					stack.push(c.left);
				} else if (c.right != null && h != c.right) {
					stack.push(c.right);
				} else {
					System.out.print(stack.pop().value + " ");
					h = c;
				}
			}
		}
		System.out.println();
	}

	public static void main(String[] args) {
		Node head = new Node(5);
		head.left = new Node(3);
		head.right = new Node(8);
		head.left.left = new Node(2);
		head.left.right = new Node(4);
		head.left.left.left = new Node(1);
		head.right.left = new Node(7);
		head.right.left.left = new Node(6);
		head.right.right = new Node(10);
		head.right.right.left = new Node(9);
		head.right.right.right = new Node(11);

		// recursive
		System.out.println("==============recursive==============");
		System.out.print("pre-order: ");
		preOrderRecur(head);
		System.out.println();
		System.out.print("in-order: ");
		inOrderRecur(head);
		System.out.println();
		System.out.print("pos-order: ");
		posOrderRecur(head);
		System.out.println();

		// unrecursive
		System.out.println("============unrecursive=============");
		preOrderUnRecur(head);
		inOrderUnRecur(head);
		posOrderUnRecur1(head);
		posOrderUnRecur2(head);

	}

}

 

posted @ 2019-01-14 23:30  Horken  阅读(119)  评论(0编辑  收藏  举报