树的各种遍历总结

x33g5p2x  于2022-03-06 转载在 其他  
字(2.1k)|赞(0)|评价(0)|浏览(401)

一、写在前面
本篇博客主要是对树的一些遍历方式进行总结,其中包含树的深度优先遍历,和树的广度优先遍历,以及二叉树的先中后序遍历,其中先中后序遍历分别使用递归版本的遍历方式和非递归版本的递归方式。
二、树的深度优先遍历和广度优先遍历

如上图所示为我们需要遍历的数结构。

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

深度优先遍历

  1. const dfs = (root) => {
  2. console.log(root.val)
  3. root.children.forEach(item => {
  4. dfs(item)
  5. })
  6. }
  7. dfs(tree)

广度优先遍历

  1. const bfs = (node) => {
  2. let queue = [node]
  3. while(queue.length > 0) {
  4. let curNode = queue.shift()
  5. console.log(curNode.val)
  6. let child = curNode.children
  7. if(child && child.length > 0) {
  8. child.forEach(item => {
  9. queue.push(item)
  10. })
  11. }
  12. }
  13. }
  14. bfs(tree)

总结:树的深度优先遍历使用的是递归,树的广度优先遍历使用的是:队列这种数据结构。
三、二叉树的先中后序遍历
database

  1. const dbs = {
  2. val: 4,
  3. left: {
  4. val: 3,
  5. left: {
  6. val: 2,
  7. left: null,
  8. right: null
  9. },
  10. right: {
  11. val: 1,
  12. left: null,
  13. right: null
  14. }
  15. },
  16. right: {
  17. val: 5,
  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. const preorder = (root) => {
  2. if(!root) return
  3. console.log(root.val)
  4. if(root.left) preorder(root.left)
  5. if(root.right) preorder(root.right)
  6. }
  7. preorder(dbs)

中序遍历

  1. const midorder = (root) => {
  2. if(!root) return
  3. if(root.left) midorder(root.left)
  4. console.log(root.val)
  5. if(root.right) midorder(root.right)
  6. }
  7. midorder(dbs)

后序遍历

  1. const afterorder = (root) => {
  2. if(!root) return
  3. if(root.left) afterorder(root.left)
  4. if(root.right) afterorder(root.right)
  5. console.log(root.val)
  6. }
  7. afterorder(dbs)

上述递归版的遍历方式太简单了,下面是非递归版的写法。
先序遍历——非递归版:使用数据结构栈

  1. const preorder = (root) => {
  2. if (!root) return
  3. let stack = [root]
  4. while (stack.length > 0) {
  5. let cur = stack.pop()
  6. console.log(cur.val)
  7. if(cur.right) stack.push(cur.right)
  8. if(cur.left) stack.push(cur.left)
  9. }
  10. }
  11. preorder(dbs)

中序遍历——非递归版

  1. const midorder = (root) => {
  2. if(!root) return
  3. let stack = []
  4. let p = root
  5. while(stack.length > 0 || p) {
  6. while(p) {
  7. stack.push(p)
  8. p = p.left
  9. }
  10. let cur = stack.pop()
  11. console.log(cur.val)
  12. p = cur.right
  13. }
  14. }
  15. midorder(dbs)

后序遍历——非递归版

  1. const postorder = (root) => {
  2. if(!root) return
  3. let stack1 = [root]
  4. let stack2 = []
  5. while(stack1.length > 0) {
  6. let cur = stack1.pop()
  7. stack2.push(cur)
  8. if(cur.left) stack1.push(cur.left)
  9. if(cur.right) stack1.push(cur.right)
  10. }
  11. while(stack2.length > 0) {
  12. let cur = stack2.pop()
  13. console.log(cur.val)
  14. }
  15. }
  16. postorder(dbs)

相关文章