We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
这种方法以深度 depth 优先为策略,从根节点开始一直遍历到某个叶子节点,然后回到根节点,在遍历另外一个分支。
根据根节点,左孩子节点和右孩子节点的访问顺序又可以将 DFS 细分为先序遍历 preorder,中序遍历 inorder 和后序遍历 postorder。
preorder
inorder
postorder
按照高度顺序,从上往下逐层遍历节点。 先遍历上层节点再遍历下层节点。
下图中按照不同的方法遍历对应子树,得到的遍历顺序都是 1-2-3-4-5。根据不同子树结构比较不同遍历方法的特点。
1-2-3-4-5
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ var preorderTraversal = function(root) { let result = []; function pre (root) { if(root !== null) { // ① 根节点 result.push(root.val); // ② 前序遍历左子树 pre(root.left); // ③ 前序遍历右子树 pre(root.right); } } pre(root); return result; };
中序遍历为:中序遍历左子树 -> 根结点 -> 中序遍历右子树
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ var inorderTraversal = function(root) { let result = []; function inorder(root) { if(root != null) { // ① 中序遍历左子树 inorder(root.left); // ② 根结点 result.push(root.val); // ③ 中序遍历右子树 inorder(root.right); } } inorder(root); return result; };
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ var postorderTraversal = function(root) { const result = []; function postorder(root) { if(root!== null) { // ① 后序遍历左子树 postorder(root.left); // ② 后序遍历右子树 postorder(root.right); // ③ 根结点 result.push(root.val); } } postorder(root); return result; };
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {number[]} inorder * @param {number[]} postorder * @return {TreeNode} */ var buildTree = function (inorder, postorder) { if (!inorder || inorder.length == 0) { return null; } // 后序遍历的最后一个节点一定是根节点 let treeNode = new TreeNode(postorder[postorder.length - 1]); // 在中序遍历中找到 根节点的位置 let i = inorder.indexOf(postorder[postorder.length - 1]); // 根据左子树的中序和后序遍历构建左子树 treeNode.left = buildTree(inorder.slice(0, i), postorder.slice(0, i)); // 根据右子树的中序和后序遍历构建右子树 treeNode.right = buildTree(inorder.slice(i + 1), postorder.slice(i, postorder.length - 1)); return treeNode; };
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {number[]} preorder * @param {number[]} inorder * @return {TreeNode} */ var buildTree = function(preorder, inorder) { if (!inorder || inorder.length == 0) { return null; } // 前序遍历的第一个节点一定是根节点 let treeNode = new TreeNode(preorder[0]); // 在中序遍历中找到 根节点的位置 let i = inorder.indexOf(preorder[0]); // 根据左子树的前序和中序遍历构建左子树 treeNode.left = buildTree(preorder.slice(1, i + 1), inorder.slice(0, i)); // 根据右子树的前序和中序遍历构建右子树 treeNode.right = buildTree(preorder.slice(i + 1), inorder.slice(i + 1)); return treeNode; };
const constructFromPrePost = (pre, post) => { const { length } = pre; if (length === 0) return null; // 前序遍历的第一个节点一定是根节点 const root = new TreeNode(pre[0]); // 在后序遍历中找到 根节点的位置 const index = post.indexOf(pre[1]); // 根据左子树的前序和后序遍历构建左子树 root.left = constructFromPrePost(pre.slice(1, index + 2), post.slice(0, index + 1)); // 根据右子树的前序和后序遍历构建右子树 root.right = constructFromPrePost(pre.slice(index + 2, length), post.slice(index + 1, length - 1)); return root; };
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[][]} */ var levelOrder = function(root) { const result = []; // level表示当前层级 function levelOrderNode(root, level) { if(root!== null) { if(result[level]) { result[level].push(root.val) } else { result[level] = [root.val]; } const nextLevel = level + 1; levelOrderNode(root.left, nextLevel); levelOrderNode(root.right, nextLevel); } } levelOrderNode(root, 0); return result; };
这次看完应该理解了树的两种遍历策略了吧,如果还不懂,建议再看一遍,或者自己去看leetcode相关的官方题解。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
两种通用的遍历树的策略
深度优先遍历(DFS)
这种方法以深度 depth 优先为策略,从根节点开始一直遍历到某个叶子节点,然后回到根节点,在遍历另外一个分支。
根据根节点,左孩子节点和右孩子节点的访问顺序又可以将 DFS 细分为先序遍历
preorder
,中序遍历inorder
和后序遍历postorder
。广度优先遍历(BFS)
按照高度顺序,从上往下逐层遍历节点。
先遍历上层节点再遍历下层节点。
下图中按照不同的方法遍历对应子树,得到的遍历顺序都是
1-2-3-4-5
。根据不同子树结构比较不同遍历方法的特点。相关题目(leetcode)
DFS
先序遍历、中序遍历、后序遍历
先序遍历为:根节点 -> 前序遍历左子树 -> 前序遍历右子树
中序遍历为:中序遍历左子树 -> 根结点 -> 中序遍历右子树
后序遍历为:后序遍历左子树 -> 后序遍历右子树 -> 根结点
根据两种遍历序列构造树
BFS
按照高度顺序,从上往下逐层遍历节点。
先遍历上层节点再遍历下层节点。
最后
这次看完应该理解了树的两种遍历策略了吧,如果还不懂,建议再看一遍,或者自己去看leetcode相关的官方题解。
The text was updated successfully, but these errors were encountered: