所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。
二叉树的遍历方式。
主要分为两种:深度优先(Depth First Search,简称DFS)和广度优先(Breadth First Search,简称BFS)。
深度优先:
先序遍历:先访问根节点,再访问左节点,最后访问右节点
中序遍历:先访问左节点,再访问根节点,最后访问右节点
后序遍历:先访问左节点,再访问右节点,最后访问根节点
广度优先:
广度优先:从顶到底一层一层的遍历
深度优先遍历法简单来说,三种排序法都是对于根节点来说的,先、中、后都是对于根节点来说,于是乎分别就是 根节点先访问、根节点中间访问、根节点最后访问,这样就很清晰了。
如上图,各种遍历方法的遍历节点顺序分别是:
先序:1→2→3
中序:2→1→3
后序:2→3→1
广度优先:2→3→1(这里和后序一样只是因为只有两层)
简单代码:
节点类
/** * 二叉树节点 */class TreeNode{ int val; TreeNode left; TreeNode right; public TreeNode(int val) { this.val = val; }}
先序遍历(递归实现)
/** * 前序遍历 * @param node 二叉树节点 */static void preOrderTraveral(TreeNode node){ if (node == null) return; //根左右 System.out.println(node.val); preOrderTraveral(node.left); preOrderTraveral(node.right);}
中序遍历(递归实现)
/** * 中序遍历 * @param node 二叉树节点 */static void inOrderTreveral(TreeNode node){ if (node == null) return; //左根右 inOrderTreveral(node.left); System.out.println(node.val); inOrderTreveral(node.right);}
后序遍历(递归实现)
/** * 后序遍历 * @param node 二叉树节点 */static void postOrderTreveral(TreeNode node){ if (node == null) return; //左右根 postOrderTreveral(node.left); postOrderTreveral(node.right); System.out.println(node.val);}
先序优先(非递归实现)
/** * 前序遍历 * @param head 二叉树节点 */public void preOrderTraveral(TreeNode head) { Dequestack = new ArrayDeque<>(); stack.push(head); while (stack != null && !stack.isEmpty()) { TreeNode node = stack.pop(); System.out.println(node.val); if(node.left == null && node.right == null) continue; // 注意顺序 if (node.right != null) stack.push(node.right); if (node.left != null) stack.push(node.left); }}
广度优先(非递归实现)
/** * 广度优先遍历 * @param node 二叉树节点 */public static void BfsTraveral(TreeNode node) { Dequequeue = new ArrayDeque<>(); queue.push(node); while (queue != null && !queue.isEmpty()) { TreeNode root = queue.pop(); System.out.println(root.val); if (root.left != null) queue.add(root.left); if (root.right != null) queue.add(root.right); }}
作为搜索算法的一种,DFS对于寻找一个解的NP(包括NPC)问题作用很大。但是,搜索算法毕竟是时间复杂度是O(n!)的阶乘级算法,它的效率非常低,在数据规模变大时,这种算法就显得力不从心了。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。
你唔收我你一定后悔