• 9、求二叉搜索树第k小值


    二叉树(Binary Tree)

    • 是一颗树
    • 每个节点,最多只能有2个子节点
    • 树节点的数据结构{ value,left?,right?}

    二叉树的遍历

    • 前序遍历:root -> left -> right (左右)
    • 中序遍历:left -> root -> right (左右)
    • 后序遍历:left -> right -> root (左右)

    代码示例

    interface IBinaryTree {
      value: number
      left: IBinaryTree | null
      right: IBinaryTree | null
    }
    
    const Tree:IBinaryTree = {
      value: 5,
      left: {
        value: 3,
        left: {
          value: 2,
          left:null,
          right:null
        },
        right:{
          value: 3,
          left: null,
          right: null
        }
      },
      right:{
        value: 7,
        left: {
          value: 6,
          left: null,
          right: null
        },
        right: {
          value: 8,
          left:null,
          right:null
        }
      }
    }
    
    /**
     * 二叉树前序遍历===> 根左右
     * @param tree 
     */
    function preOrderTraverse (tree:IBinaryTree) {
      if (!tree) return
    
      console.log(tree.value)
      preOrderTraverse(tree.left as IBinaryTree)
      preOrderTraverse(tree.right as IBinaryTree)
    }
    
    /**
     * 二叉树中序遍历===> 左根右
     * @param tree 
     */
    function inOrderTraverse (tree: IBinaryTree) {
      if (!tree) return
    
      inOrderTraverse(tree.left as IBinaryTree)
      console.log(tree.value)
      inOrderTraverse(tree.right as IBinaryTree)
    }
    
    /**
     * 二叉树后续遍历===> 左右根
     * @param tree 
     */
    function postOrderTraverse (tree: IBinaryTree) {
      if (!tree) return
    
      postOrderTraverse(tree.left as IBinaryTree)
      postOrderTraverse(tree.right as IBinaryTree)
      console.log(tree.value)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    功能测试

    • 前序遍历
    preOrderTraverse(Tree)
    
    • 1

    结果

    5
    3
    2
    4
    7
    6
    8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 中序遍历
    inOrderTraverse(Tree)
    
    • 1

    结果

    2
    3
    4
    5
    6
    7
    8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 后续遍历
    postOrderTraverse(Tree)
    
    • 1

    结果

    2
    4
    3
    6
    8
    7
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二叉搜索树 BST (Binary Search Tree)

    • left(包括其后代)value <= root value
    • right(包括其后代)value >= root value
    • 可使用二分法进行快速查找

    解题思路

    • BST使用中序遍历,即从小到大的排序
    • 找到排序后的第k值即可

    代码实现

    const arr:number[] = []
    
    /**
     * 二叉树中序遍历===> 左根右
     * @param tree 
     */
    function inOrderTraverse (tree: IBinaryTree) {
      if (!tree) return
    
      inOrderTraverse(tree.left as IBinaryTree)
      // console.log(tree.value)
      arr.push(tree.value)
      inOrderTraverse(tree.right as IBinaryTree)
    }
    
    /**
    * 获取二叉树第K值
    */
    function getKthValue(tree:IBinaryTree,k:number):number | null {
      inOrderTraverse(tree)
      return arr[k-1] || null
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    功能测试

    console.log(getKthValue(Tree,2))//3
    
    • 1

    这里的4恰好是数组下标1对应的数,即arr[k-1] === 4.

    单元测试

    describe('二叉搜索树',() => {
        const Tree:IBinaryTree = {
          value: 5,
          left: {
            value: 3,
            left: {
              value: 2,
              left:null,
              right:null
            },
            right:{
              value: 4,
              left: null,
              right: null
            }
          },
          right:{
            value: 7,
            left: {
              value: 6,
              left: null,
              right: null
            },
            right: {
              value: 8,
              left:null,
              right:null
            }
          }
        }
    
        it('正常情况',() => {
          const res = getKthValue(Tree,2)
          expect(res).toBe(3)
        })
    
        it('k 超出范围时',() => {
          const res = getKthValue(Tree,10)
          expect(res).toBeNull()
        })
    
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    总结

    • 二叉树,和三种(前序、中序、后序)遍历
    • 二叉搜索树的特点:left <= root;right >= root
    • 二叉搜索树的价值:可使用二分法进行快速查找
  • 相关阅读:
    谷粒学院——Day08【课程发布-课程大纲和课程发布】
    Python3 基础语法
    基于VUE + Echarts 实现可视化数据大屏快递业务数据
    Java:现实世界中最流行的10个Java应用程序示例
    Oracle安全基线检查
    无需插数据线,adb通过wifi无线调试
    win7常见问题
    【排列组合】
    半导体行业如何在跨网数据交换时保证核心数据是安全的?
    小白必知必会的几个IP地址知识
  • 原文地址:https://blog.csdn.net/qq_36362721/article/details/127680731