树的遍历 | 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).

你可能感兴趣的:(tree)