二叉树的非递归遍历-java实现

二叉树的先序,中序,和后续遍历,采用非递归的形式

一、先序遍历:(自己做一个栈)

  1. 压入根节点,再从栈顶弹出
  2. 如果弹出的节点的右孩子不为空,就先把右孩子压栈,左孩子不为空,就把左孩子后压栈
	//非递归实现先序遍历
public static void preOrderUnRecur(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.push(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();
	}

二、 中序遍历

  1. 当前节点不为空,就把这个节点压栈,然后节点移动到左孩子
  2. 当前节点为空,就把栈顶的元素弹出,节点移动到右孩子
//非递归实现中序遍历
	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;//执行完if判断之后,进入下一次的while循环 
				} else {
					head = stack.pop();
					System.out.print(head.value + " ");
					head = head.right;
				}
			}
		}
		System.out.println();
	}

三、后序遍历(左右中)

方法1:使用两个栈

  1. 思想:
    先序是中左右,可以改成中右左(压栈的时候先压左孩子,再压右孩子),对应中右左遍历之后可以先不打印,依次存入栈中,再从栈中依次弹出,结果就是左中右。
//非递归实现后序遍历--------方法1用两个栈(中右左的逆序左右中)
	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()) {//打印栈2
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

方法2:使用一个栈(可以不掌握)

//非递归实现后序遍历--------方法2用一个栈(不用掌握)
	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 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 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);

	}

输出结果对比

==============recursive==============
pre-order: 5 3 2 1 4 8 7 6 10 9 11 
in-order: 1 2 3 4 5 6 7 8 9 10 11 
pos-order: 1 2 4 3 6 7 9 11 10 8 5 
============unrecursive=============
pre-order: 5 3 2 1 4 8 7 6 10 9 11 
in-order: 1 2 3 4 5 6 7 8 9 10 11 
pos-order: 1 2 4 3 6 7 9 11 10 8 5 
pos-order: 1 2 4 3 6 7 9 11 10 8 5 

你可能感兴趣的:(数据结构与算法总结)