一棵树

  1. const tree = {
  2. val: "a",
  3. children: [
  4. {
  5. val: "b",
  6. children: [
  7. {
  8. val: "d",
  9. children: [],
  10. },
  11. {
  12. val: "e",
  13. children: [],
  14. },
  15. ],
  16. },
  17. {
  18. val: "c",
  19. children: [
  20. {
  21. val: "f",
  22. children: [],
  23. },
  24. {
  25. val: "g",
  26. children: [],
  27. },
  28. ],
  29. },
  30. ],
  31. };

搜索算法

DFS 深度优先遍历

递归

  1. const dfs = node => {
  2. console.log(node.val);
  3. node.children.forEach(dfs);
  4. };
  5. dfs(tree);

BFS 广度优先遍历

维护一个队列,将每一层的结点推入队列,最后打印

  1. const bfs = node => {
  2. const queue = [node];
  3. while (queue.length > 0) {
  4. const n = queue.shift();
  5. console.log(n.val);
  6. n.children.forEach(child => {
  7. queue.push(child);
  8. });
  9. }
  10. };

二叉树的遍历

二叉树

  1. const binaryTree = {
  2. val: 1,
  3. left: {
  4. val: 2,
  5. left: {
  6. val: 4,
  7. left: null,
  8. right: null,
  9. },
  10. right: {
  11. val: 5,
  12. left: null,
  13. right: null,
  14. },
  15. },
  16. right: {
  17. val: 3,
  18. left: {
  19. val: 6,
  20. left: null,
  21. right: null,
  22. },
  23. right: {
  24. val: 7,
  25. left: null,
  26. right: null,
  27. },
  28. },
  29. };

递归版

  1. 先序遍历:根左右
  2. 中序遍历:左中右
  3. 后序遍历:左右中
  1. const prevOrder = node => {
  2. if (!node) return;
  3. console.log(node.val);
  4. prevOrder(node.left);
  5. prevOrder(node.right);
  6. };
  7. const inOrder = node => {
  8. if (!node) return;
  9. prevOrder(node.left);
  10. console.log(node.val);
  11. prevOrder(node.right);
  12. };
  13. // 后序遍历:左右中
  14. const postOrder = node => {
  15. if (!node) return;
  16. postOrder(node.left);
  17. postOrder(node.right);
  18. console.log(node.val);
  19. };

非递归版:维护栈

  1. prevOrder:利用栈FILO,先入栈右节点,其次是左节点,最后依次打印
  2. inOrder:先入栈左节点直到为null,依次出栈输出,同时入栈出栈结点的右节点(如果有)并出栈,如此循环
  3. 维护两个栈,一个控制过程,另一个outStk存放输出顺序
    1. 根结点一定是最后输出,所以先入栈outStk
    2. 其次是入栈找到的右
    3. 最后入栈左节点 ```javascript const prevOrder = node => { // 利用栈的先进后出FILO if (!node) return; const stk = [node]; while (stk.length > 0) { const curr = stk.pop(); console.log(curr.val); if (curr.right) stk.push(curr.right); if (curr.left) stk.push(curr.left); } };

const inOrder = node => { / 维护一个栈,先将左节点一层层放入栈中直到没有 此时依次出栈,打印出当前出栈结点的同时,将当前结点的右节点(如果有)推入栈中,再出栈 循环直到栈为空 /

  1. if (!node) return;
  2. const stk = [];
  3. let curr = node;
  4. while (curr || stk.length > 0) {
  5. while (curr) {
  6. stk.push(curr);
  7. curr = curr.left;
  8. }
  9. const last = stk.pop();
  10. console.log(last.val);
  11. curr = last.right;
  12. }

}; const postOrder = node => { / 维护两个栈,一个控制过程,另一个存放输出顺序 根结点一定是最后输出,所以先入栈 其次是入栈找到的右节点 最后是左节点 / if (!node) return; const stk = [node]; const outStk = []; while (stk.length) { const curr = stk.pop(); outStk.push(curr) if (curr.left) stk.push(curr.left); if (curr.right) stk.push(curr.right); } while(outStk.length) { console.log(outStk.pop().val ) } };

  1. <a name="aWCHR"></a>
  2. # 遍历JSON所有的节点(清理JSON)
  3. ```javascript
  4. const json = {
  5. a: { b: { c: 1 } },
  6. d: [1, 2],
  7. };
  8. const dfs = (n, path) => {
  9. console.log(n, path);
  10. Object.keys(n).forEach(k => {
  11. dfs(n[k], path.concat(k));
  12. });
  13. };
  14. dfs(json, []);