樹的遍歷 | Tree Traversal


樹的遍歷方式總體上有兩種:DFS和BFS;

其中DFS包含了前序、中序和后序遍歷,而BFS則為層次遍歷。

 

DFS的實現方式:

(1) 遞歸;

(2) 非遞歸,使用輔助棧;

 

遞歸程序

public class Recursion {
	public void preorderRec(TreeNode root) {
		if (root == null) {
			return;
		}
		System.out.println(root.val); // visit the node
		preorderRec(root.left);
		preorderRec(root.right);
	}

	public void inorderRec(TreeNode root) {
		if (root == null) {
			return;
		}
		preorderRec(root.left);
		System.out.println(root.val); // visit the node
		preorderRec(root.right);
	}

	public void postorderRec(TreeNode root) {
		if (root == null) {
			return;
		}
		preorderRec(root.left);
		preorderRec(root.right);
		System.out.println(root.val); // visit the node
	}
}

 

非遞歸程序

public class NoRecursion {
	public void preorder(TreeNode root) {
		if (root == null) {
			return;
		}

		Stack<TreeNode> s = new Stack<TreeNode>();
		TreeNode node = root;

		while (node != null || !s.isEmpty()) {
			while (node != null) {
				System.out.println(node.val); // visit the node
				s.push(node);
				node = node.left;
			}

			if (!s.isEmpty()) {
				node = s.pop();
				node = node.right;
			}
		}
	}

	public void inorder(TreeNode root) {
		if (root == null) {
			return;
		}

		Stack<TreeNode> s = new Stack<TreeNode>();
		TreeNode node = root;
		while (node != null || !s.isEmpty()) {
			while (node != null) {
				s.push(node);
				node = node.left;
			}

			if (!s.isEmpty()) {
				node = s.pop();
				System.out.println(node.val);
				node = node.right;
			}
		}
	}

	public void postorder(TreeNode root) {
		if (root == null) {
			return;
		}

		Stack<TreeNode> s = new Stack<TreeNode>();
		TreeNode node = root;
		TreeNode pre = null;

		while (node != null || !s.isEmpty()) {
			while (node != null) {
				s.push(node);
				node = node.left;
			}

			if (!s.isEmpty()) {
				node = s.peek();
				if (node.right != null && node.right != pre) {
					node = node.right;
				} else {
					node = s.pop();
					pre = node; // pre point the last visited node
					System.out.println(node.val); // visit the node
					node = null;
				}
			}
		}
	}
}

 

其中,后序遍歷稍微困難了一點,主要原因在於在遍歷樹中節點的同時需要記錄最后訪問節點。舉例說明,如有一棵樹如下:

1

|  \

2   3

       \

         4

后序遍歷的做法如下:

(1) 將根節點的左節點們依次加入棧中,最后棧頂元素為左子樹的最左節點;

(2) 拿到棧頂元素(此時不出棧),如果沒有右孩子並且右孩子沒有被訪問過,則出棧,此時標記下該出棧元素(表示該元素已被訪問過);否則節點指向其右孩子。然后到(1);

(3) 遍歷程序的結束條件為棧為空並且節點為空;

 

時間/空間復雜度分析

時間復雜度均為O(n);空間復雜度平均情況下為O(logn),最壞情況下為O(n).

 

BFS的實現方式:

層次遍歷,使用一個輔助隊列。

 

public void levelTraversal(TreeNode root){
	if (root == null) {
		return ;
	}
	
	Queue<TreeNode> q = new LinkedList<TreeNode>();
	q.offer(root);
	
	while (!q.isEmpty()) {
		int size = q.size();
		for (int i = 0; i < size; i++) {
			TreeNode node = q.poll();
			System.out.println(node.val); // visit the node
			if (node.left!=null) {
				q.offer(node.left);
			}
			if (node.right!=null) {
				q.offer(node.right);
			}
		}
	}
}

時間復雜度和空間復雜度均為O(n).


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM