js二叉树

二叉树的意思就是说:每个节点不能多于有两个儿子

  • 一棵树至少会有一个节点(根节点)
  • 树由节点组成,而节点的定义就是:一个数据、两个指针(如果有节点就指向节点、没有节点就指向null)
  • 因此,我们定义树的时候往往是**->定义节点->节点连接起来就成了树**,

二叉树中还有一种特殊的二叉树:二叉查找树(binary search tree)

  • 定义:当前根节点的左边全部比根节点小,当前根节点的右边全部比根节点大。
    • 明眼人可以看出,这对我们来找一个数是非常方便快捷的

使用js创建一个二叉查找树

function Node(key) {
  this.key = key;
  this.left = null;
  this.right = null;
}
function BinarySearchTree() {
  this.root = null;
}
// 查询树排序插入
function insertNode(node, newNode) {
  // 如果新节点值小于当前节点值,则插入左子节点
  if (newNode.key < node.key) {
    if (node.left === null) {
      node.left = newNode;
    } else {
      insertNode(node.left, newNode);
    }
  } else {
    // 如果新节点值大于当前节点值,则插入右子节点
    if (node.right === null) {
      node.right = newNode;
    } else {
      insertNode(node.right, newNode);
    }
  }
}
// 插入
BinarySearchTree.prototype.insert = function (key) {
  let newNode = new Node(key);
  if (this.root === null) {
    this.root = newNode;
  } else {
    insertNode(this.root, newNode);
  }
}

let tree = new BinarySearchTree()
tree.insert(19)
tree.insert(10)
tree.insert(20)
tree.insert(23)
tree.insert(1)
tree.insert(18)
console.log(tree)

打印出来的效果

 

 创建的二叉树结构就是下图所示

 

 

遍历二叉树

二叉树遍历有三种方式

  • 先序遍历
    • 先访问根节点,然后访问左节点,最后访问右节点(根->左->右)
  • 中序遍历
    • 先访问左节点,然后访问根节点,最后访问右节点(左->根->右)
  • 后序遍历
    • 先访问左节点,然后访问右节点,最后访问根节点(左->右->根)

以上面的二叉树为例:

  • 如果是先序遍历19->10->1->18->20->23
  • 如果是中序遍历1->10->18->19->20->23
  • 如果是后序遍历1->18->10->23->20->19
let tree = new BinarySearchTree()
tree.insert(19)
tree.insert(10)
tree.insert(20)
tree.insert(23)
tree.insert(1)
tree.insert(18)
// console.log(tree)
// 先序遍历
function preTraverseBTree(treeNode) {
  if(treeNode !== null) {
    console.log(treeNode.key)
    preTraverseBTree(treeNode.left)
    preTraverseBTree(treeNode.right)
  }
}
// 中序遍历
function inTraverseBTree(treeNode) {
  if(treeNode !== null) {
    inTraverseBTree(treeNode.left)
    console.log(treeNode.key)
    inTraverseBTree(treeNode.right)
  }
}
// 后序遍历
function afterTraverseBTree(treeNode) {
  if(treeNode !== null) {
    afterTraverseBTree(treeNode.left)
    afterTraverseBTree(treeNode.right)
    console.log(treeNode.key)
  }
}
console.log('先序遍历')
preTraverseBTree(tree.root)
console.log('中序遍历')
inTraverseBTree(tree.root)
console.log('后序遍历')
afterTraverseBTree(tree.root)

 

 

无论先中后遍历,每个节点的遍历如果访问有孩子的节点,先处理孩子的(逻辑是一样的)

  • 因此我们很容易想到递归
  • 递归的出口就是:当没有子节点了,就返回

 

posted @ 2021-10-08 18:41  瑞瑞大人  阅读(349)  评论(0编辑  收藏  举报