二叉树的基础

本片文章参考:https://www.yuque.com/mazhuan/er7l7d/cdim2i

备注:

前序遍历:根左右

后序遍历:左根右

中序遍历:左右根

知识点:

  1. 二叉树的前序遍历
  2. 二叉树的中序遍历
  3. 二叉树的后序遍历
  4. 层次遍历
  5. 广度优先遍历(BFS)
  6. 深度优先遍历(DFS)

js—API

shift:移除数组开头的数字

unshift:在数组开头添加一个数字

图1

二叉树基础 - 图1

代码1

  1. const treeOjb = {
  2. val:1,
  3. left:{
  4. val:2,
  5. left:{
  6. val:4,
  7. },
  8. right:{
  9. val:5,
  10. left:{
  11. val:7
  12. },
  13. right:{
  14. val:8,
  15. },
  16. },
  17. },
  18. right:{
  19. val:3,
  20. right:{
  21. val:6,
  22. },
  23. },
  24. }

前序优先遍历(深度优先遍历)

二叉树基础 - 图2

递归思路

  • 打印当前节点的值
  • 递归调用自身,传入左子树
  • 递归调用自身,传入右子树
  1. const arr = []
  2. const treeOjb = {
  3. val:1,
  4. left:{
  5. val:2,
  6. left:{
  7. val:4,
  8. },
  9. right:{
  10. val:5,
  11. left:{
  12. val:7
  13. },
  14. right:{
  15. val:8,
  16. },
  17. },
  18. },
  19. right:{
  20. val:3,
  21. right:{
  22. val:6,
  23. },
  24. },
  25. }
  26. function PreorderSearchBinaryTree(treeOjb){
  27. if(!treeOjb){
  28. return undefined
  29. } else {
  30. arr.push(treeOjb.val)
  31. PreorderSearchBinaryTree(treeOjb.left)
  32. PreorderSearchBinaryTree(treeOjb.right)
  33. }
  34. }
  35. PreorderSearchBinaryTree(treeOjb)
  36. // console.log(PreorderSearchBinaryTree(treeOjb))
  37. // 此处会重新调用一次
  38. console.log(arr)

非递归思路

  • 将根节点塞入栈
  • 执行以下循环,当栈为空结束循环
    • 推出栈中的第一个节点
    • 检测是否有右子树,如果有,塞入栈
    • 检测是否有左子树,如果有,塞入栈
    • 打印当前推出节点的值
  1. const treeOjb = {
  2. val:1,
  3. left:{
  4. val:2,
  5. left:{
  6. val:4,
  7. },
  8. right:{
  9. val:5,
  10. left:{
  11. val:7
  12. },
  13. right:{
  14. val:8,
  15. },
  16. },
  17. },
  18. right:{
  19. val:3,
  20. right:{
  21. val:6,
  22. },
  23. },
  24. }
  25. function fun(treeOjb) {
  26. const result = []
  27. const stack = [treeOjb]
  28. let currentNode
  29. while(stack.length > 0){
  30. currentNode = stack.pop()
  31. if(currentNode.right){
  32. stack.push(currentNode.right)
  33. }
  34. if(currentNode.left){
  35. stack.push(currentNode.left)
  36. }
  37. result.push(currentNode.val)
  38. }
  39. return result
  40. }
  41. console.log(fun(treeOjb));

后序遍历

二叉树基础 - 图3

递归版代码:

  1. const tree = {
  2. val:1,
  3. left:{
  4. val:2,
  5. left:{
  6. val:4,
  7. },
  8. right:{
  9. val:5,
  10. left:{
  11. val:7
  12. },
  13. right:{
  14. val:8,
  15. },
  16. },
  17. },
  18. right:{
  19. val:3,
  20. right:{
  21. val:6,
  22. },
  23. },
  24. }
  25. const arr = []
  26. function afterRecursion(tree) {
  27. if(!tree){
  28. return undefined
  29. }
  30. afterRecursion(tree.left)
  31. afterRecursion(tree.right)
  32. arr.push(tree.val)
  33. }
  34. afterRecursion(tree)
  35. console.log(arr)

非递归代码:

  1. const tree = {
  2. val:1,
  3. left:{
  4. val:2,
  5. left:{
  6. val:4,
  7. },
  8. right:{
  9. val:5,
  10. left:{
  11. val:7
  12. },
  13. right:{
  14. val:8,
  15. },
  16. },
  17. },
  18. right:{
  19. val:3,
  20. right:{
  21. val:6,
  22. },
  23. },
  24. }
  25. function afterNoRecursion(tree) {
  26. const result = []
  27. // 根节点塞入栈
  28. const stack = [tree]
  29. let currentNode
  30. while(stack.length > 0){
  31. // 推出栈中的第一个节点
  32. currentNode = stack.pop()
  33. // 如果有左节点,左节点入栈
  34. if(currentNode.left){
  35. stack.push(currentNode.left)
  36. }
  37. // 如果有右节点,右节点入栈
  38. if(currentNode.right){
  39. stack.push(currentNode.right)
  40. }
  41. // 打印当前节点
  42. result.unshift(currentNode.val)
  43. }
  44. return result
  45. }
  46. console.log(afterNoRecursion(tree))

中序遍历

二叉树基础 - 图4

递归的思想

  1. const arr = []
  2. const treeOjb = {
  3. val:1,
  4. left:{
  5. val:2,
  6. left:{
  7. val:4,
  8. },
  9. right:{
  10. val:5,
  11. left:{
  12. val:7
  13. },
  14. right:{
  15. val:8,
  16. },
  17. },
  18. },
  19. right:{
  20. val:3,
  21. right:{
  22. val:6,
  23. },
  24. },
  25. }
  26. function middleRecursion(treeOjb){
  27. if(!treeOjb){
  28. return undefined
  29. }else {
  30. middleRecursion(treeOjb.left)
  31. arr.push(treeOjb.val)
  32. middleRecursion(treeOjb.right)
  33. }
  34. }
  35. middleRecursion(treeOjb)
  36. console.log(arr)

非递归的思想

  1. const treeOjb = {
  2. val:1,
  3. left:{
  4. val:2,
  5. left:{
  6. val:4,
  7. },
  8. right:{
  9. val:5,
  10. left:{
  11. val:7
  12. },
  13. right:{
  14. val:8,
  15. },
  16. },
  17. },
  18. right:{
  19. val:3,
  20. right:{
  21. val:6,
  22. },
  23. },
  24. }
  25. function middleNoRecursion(root){
  26. const stack = []
  27. const result = []
  28. if(!root){
  29. return []
  30. }else{
  31. while(root || stack.length !== 0){
  32. while (root){
  33. stack.push(root)
  34. root = root.left
  35. }
  36. root = stack.pop()
  37. result.push(root.val)
  38. root = root.right
  39. }
  40. }
  41. return result
  42. }
  43. console.log(middleNoRecursion(treeOjb))

层序优先遍历(广度队列版)

image.png

  1. const treeOjb = {
  2. val:1,
  3. left:{
  4. val:2,
  5. left:{
  6. val:4,
  7. },
  8. right:{
  9. val:5,
  10. left:{
  11. val:7
  12. },
  13. right:{
  14. val:8,
  15. },
  16. },
  17. },
  18. right:{
  19. val:3,
  20. right:{
  21. val:6,
  22. },
  23. },
  24. }
  25. function irregular(node){
  26. let result = [];
  27. let queue = [];
  28. queue.push(node);
  29. while(queue.length) {
  30. node = queue.shift();
  31. result.push(node.val); // 不要忘记访问
  32. // console.log(node.value);
  33. node.left && queue.push(node.left);
  34. node.right && queue.push(node.right);
  35. }
  36. return result;
  37. }
  38. console.log(irregular(treeOjb));