1. 程式人生 > >關於二叉樹的遍歷:遞迴方式和非遞迴方式

關於二叉樹的遍歷:遞迴方式和非遞迴方式

首先來定義樹的節點:

package test2018925.findTree;

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

然後來寫我們遍歷方法:

package test2018925.test;

import java.util.Stack;

import test2018925.findTree.Node;

public class Main {
	// 遞迴先序遍歷
	public void preOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		System.out.println(head.value);
		preOrderRecur(head.left);
		preOrderRecur(head.right);
	}

	// 遞迴中序遍歷
	public void inOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		preOrderRecur(head.left);
		System.out.println(head.value);
		preOrderRecur(head.right);
	}

	// 遞迴後序遍歷
	public void postOrderRecur(Node head) {
		if (head == null) {
			return;
		}
		preOrderRecur(head.left);
		preOrderRecur(head.right);
		System.out.println(head.value);
	}

	// 樹的非遞迴前序遍歷
	public void preOrderUnCur(Node head) {

		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.push(head);

			while (!stack.isEmpty()) {
				head = stack.pop();// 指標每次指向棧頂,每次取出棧頂,
				System.out.println(head.value);
				// 下邊先放右在放左,然後回到while迴圈,取出棧頂的左(不過會在放入該左子樹的右子樹和左子樹)和棧頂的右子樹
				if (head.right != null) {
					stack.push(head.right);
				}
				if (head.left != null) {
					stack.push(head.left);
				}
			}
		}
	}

	// 樹的非遞迴中序遍歷,先把左邊的左邊的左邊....全部放入壓入棧,直到沒得左子樹,就取出來,取出該節點後,再取出該節點的右子樹
	public void inOrderUnCur(Node head) {

		if (head != null) {
			Stack<Node> stack2 = new Stack<Node>();
			while (!stack2.isEmpty() || head != null) {
				if (head != null) {
					stack2.push(head);// 最開始指標指向頭
					head = head.left;// 然後指標指向左
				} else {// 當左子樹為null的時候開始進入下邊,先取出該節點,然後指標指向右邊
					head = stack2.pop();
					System.out.println(head.value);
					head = head.right;
				}

			}
		}
	}

	// 樹的非遞迴後序遍歷
	public void postOrderUnCur(Node head) {
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();
			s1.push(head);
			while (!s1.isEmpty()) {
				head = s1.pop();// 取出棧頂元素,放入下邊一行的棧2中
				s2.push(head);// 先把棧1中的頭放入到棧2中,所以頭在棧2的棧底
				if (head.left != null) {
					s1.push(head.left);// 在把左邊放入棧1,後把右邊放入棧,同時,因為我們指標始終指向我們棧頂的,所以,我們我們後邊會先把右邊放入棧2,在把左邊放入棧2.所以後邊棧2取出順序是左右中
				}
				if (head.right != null) {
					s1.push(head.right);
				}
			}
			while (!s2.isEmpty()) {
				System.out.println(s2.pop().value + " ");
			}
		}
	}
}