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

时间: 2024-10-20 11:56:18

树的遍历 | Tree Traversal的相关文章

11.3~11.4树的遍历(Tree Traversal)

11.3~11.4树的遍历(Tree Traversal) 通用地址系统(Universal address systems) 利用某种方式给树的顶点进行编号,具体如下(根默认为0): 遍历算法(Traversal algorithms) 前序遍历(Preorder traversal):根左右 中序遍历(Inorder traversal):左根右 后序遍历(Postorder traversal):左右根 深度优先搜索-DFS(Depth-first search) 广度优先搜索-BFS(B

POJ2255 Tree Recovery 【树的遍历】

Tree Recovery Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11365   Accepted: 7128 Description Little Valentine liked playing with binary trees very much. Her favorite game was constructing randomly looking binary trees with capital le

PAT Advanced 1086 Tree Traversals Again (25) [树的遍历]

题目 An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); po

Codeforces 29D Ant on the Tree 树的遍历 dfs序

题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径,要求遍历叶子节点时按照给定叶子节点的先后顺序访问. 思路: 给每个节点加一个优先级. 把最后一个叶子节点到父节点的路径上的点优先级改为1 把倒数第二个叶子节点到父节点的路径上的点优先级改为2 如此每个点就有一个优先级,每个访问儿子节点时先访问优先级大的即可 对于无解的判断:得到的欧拉序列不满足输入的叶子节点顺序即是无解. #include <cstdio> #

C++ Binary Tree Traversal

关于二叉树的遍历有很多的方法, 下面介绍两个经典的遍历算法: BFS和DFS.一个是深度优先遍历, 一个是广度有优先遍历. 这两种遍历算法均属于盲目的遍历算法, 一般而言, 启发式的遍历搜索算法比较好一些. . 关于各种遍历算法的对比, 将会在后面逐一提及. 这里不在赘述. 由于树是一个非线性的数据结构, 显然不能像linked list , 或者Array那样通过从头像最末尾移动去实现遍历每一个元素, 我们使用的是BFS和DFS算法. 例如下面的一个二叉树: 所谓的树遍历(Tree trave

树和树的遍历

二叉树 二叉树的基本概念 二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree) 二叉树的性质(特性) 性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)性质2: 深度为k的二叉树至多有2^k - 1个结点(k>0)性质3: 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;性质4:具有n个结点的完全二叉树的深度必为 log

pat L2-006. 树的遍历

L2-006. 树的遍历 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(<=30),是二叉树中结点的个数.第二行给出其后序遍历序列.第三行给出其中序遍历序列.数字间以空格分隔. 输出格式: 在一行中输出该树的层序遍历的序列.数字间以1个空格分隔,行首尾不得有多余空格. 输入样例: 7 2

leetcode404-----简单的树的遍历

Find the sum of all left leaves in a given binary tree. Example: 3 / 9 20 / 15 7 There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24. 题目给出的意思很简单.就只是单纯的树的遍历而已.意思是计算出所有左叶子节点的值的和. 我采用递归的方式表示我的遍历顺序,其实主要的是要理解题目的意思,这里

如果Google面试让你用python写一个树的遍历程序

前几天忽然对python很感兴趣,学了几天也感觉它非常的简洁实用.打破了我这么长时间对java C# C 和vb的审美疲劳,让我眼前一亮."就像读英文一样简单"这句话评价python说的很合理. 我对python的好感很大部分是因为听说google很多程序用python,而且在google app engine里面和支持python.如果你去google面试或者笔试,很可能就会考到这个题:用python实现树的遍历. 自己试着写了一下,不过毕竟是菜鸟,有问题请多多指教. 运行效果如下: