资讯专栏INFORMATION COLUMN

我对JS树的简单学习

legendmohe / 2529人阅读

摘要:二叉搜索树这一数据结构综合了以上两种数据结构的优点。上图就展示了一个二叉搜索树。实现二叉树的算法大部分都有递归。

一种非顺序数据结构-树,它对于存储需要快速查找的数据非常有用

相关概念:

根节点:位于树顶部的节点,没有父节点

内部节点:至少有一个子节点的节点(7,5,9,15,13,20)

外部节点(叶节点):没有子元素的节点(第3层)

子树:由节点和它的后代构成(节点13,12,14构成了一个子树)

深度:节点的深度取决于它的祖先节点的数量

高度:取决于所有节点深度的最大值

二叉搜索树(BST)

无序链表在插入时候具有较高的灵敏性,而有序数组在查找的时候具有较高的效率。

二叉搜索树(BST)这一数据结构综合了以上两种数据结构的优点。但是它只允许你在左侧节点存储(比父节点)小的值,右侧节点存储(比父节点)大的值。

上图就展示了一个二叉搜索树。实现二叉树的算法大部分都有递归。

创建一个BinarySearchTree类

function BinarySearchTree () {
  var Node = function () {
    this.key = key; // 键
    this.left = null; // 指针指向左侧子节点
    this.right = null; // 指针指向右侧子节点
  };
  var root = null;
}

var tree = new BinarySearchTree();

实现insert(key)方法,插入一个键

this.insert = function (key) {
  var newNode = new Node(kye); // 创建用来表示新节点的Node类实例,
  if (root === null) { // 如果插入的节点是树第一个节点
    root = newNode;
  } else {
    insertNode(root, newNode); // 私有的辅助函数
  }
}

tree.insert();

私有的辅助函数

var insertNode = function (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);
    }
  }
}
二叉树的遍历

前序遍历:根节点->左子树->右子树

中序遍历:左子树->根节点->右子树

后序遍历:左子树->右子树->根节点

对下面的树进行遍历

前序遍历:abdefgc

中序遍历:debgfac

后序遍历:edgfbca

中序遍历:一种应用是对树进行排序操作

this.inOrderTraverse = function {callback} {
  inOrderTraverse(root, callback); // 回调函数用来处理遍历到的每个节点
};
var inOrderTraverseNode = function (node, callback) {
  if (node !== null) {
    inOrderTraverseNode(node.left, callback);
    callback(node.key);
    inOrderTraverseNode(node.right, callback);
  }
}

先序遍历:一种应用是打印一个结构化的文档

this.preOrderTraverse = function (callback) {
  preOrderTraverseNode(root, callback);
}

var preOrderTraverseNode = function (node, callback) {
  if (node !== null) {
    callback(node.key);
    preOrderTraverseNode(node.left, callback);
    preOrderTraverseNode(node.right, callback);
  }
}

后序遍历:一种应用是计算一个目录和它的子目录中所有文件所占的空间大小。

this.postOrderTraverse = function (callback) {
  postOrderTraverse(root, callback);
}

var postOrderTraverse = function (callback) {
  if (node !== null) {
    postOrderTraverse(node.left, callback);
    postOrderTraverse(node.right, callback);
    callback(node.key);
  }
}
搜索树中的值

对于寻找最小值,总是沿着树的左边;对于寻找最大值,总是沿着树的右边

寻找树中的最小键

this.min = function () {
  return minNode(root);
}

var minNode = function (node) {
  if (node) {
    while (node && node.left !== null) {
      node = node.left;
    }
    return node.key;
  }
  return null;
}

寻找一个特定的值

this.search = function (key) {
  return searchNode(root, key);
}

var searchNode = function (node, kye) {
  if (node === null) { // node有效性检查
    return false;
  }
  if (key < node.key) { // 比当前节点小,当前节点的左侧子树搜索
    return searchNode(node.left, key);
  } else if (key > node.key) { // 比当前节点大,当前节点的右侧子树搜索
    return searchNode(node.right, key);
  } else { // 要找的键就是当前节点
    return true;
  }
}
移除一个节点
this.remove = function (key) {
  root = removeNode (root, key);
}

var removeNode = function (node, key) {
  if (node === null) { // 键不存在于树中
    return null;
  }
  if (key < node.key) {
    node.left = removeNode(node.left, key);
    return node;
  } else if (key > node.key) {
    node.right = removeNode(node.right, key);
    return node;
  } else {
    if (node.left === null && node.right === null) { // 一个叶节点
      node = null;
      return node;
    }
    if (node.left === null) { // 一个只有一个子节点的节点 
      node = node.right;
      return node;
    } else if (node.right === null) {
      node = node.left;
      return node;
    }

    // 一个有两个子节点的节点
    var aux = findMinNode(node.right);
    node.key = aux.key;
    node.right = removeNode(node.right, aux.key);
    return node;
  }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82448.html

相关文章

  • JavaScript算法之二叉搜索树

    摘要:二叉搜索树的特性二叉搜索树由于其独特的数据结构,使得其无论在增删,还是查找,时间复杂度都是,为二叉树的高度。二叉搜索树的查找查找很简单,根据左子节点比该节点小,右子节点比该节点大的原则进行循环判断即可。 什么是二叉树 二叉树就是树的每个节点最多只能有两个子节点 什么是二叉搜索树 二叉搜索树在二叉树的基础上,多了一个条件,就是二叉树在插入值时,若插入值比当前节点小,就插入到左节点,否则插...

    khlbat 评论0 收藏0
  • 我对JS字典的简单学习

    摘要:我对字典的简单学习字典的概念集合字典和散列表都可以来存储不重复的值。字典也被称为映射。中有集合类的实现,也有字典类的实现。相关操作方法实现方法,判断某个键值是否在这个字典中,有则返回。实现方法,将字典所有的值以数组的形式返回。 我对JS字典的简单学习 字典的概念 集合、字典和散列表都可以来存储不重复的值。在集合中我们使用[值,值]来保存,在字典和散列表中使用[键,值]来存储数据。 字典...

    CntChen 评论0 收藏0
  • 我对JS栈的简单学习

    摘要:我对栈的学习因为是个新手,所以都是最简单的知识学习梳理。栈是一种遵从后进先出原则的有序集合,新添加的或者待删除的元素都保留在栈的末尾,称作栈顶,另一端叫做栈底。栈的学习栈的创建创建一个类来表示栈。对于栈来说只能用和方法来进行添加和删除元素。 我对栈的学习 因为是个新手,所以都是最简单的知识学习梳理。 什么是栈 数组是计算机科学中最常用的数据结构,是数据元素的集合。有时候我们需要一种添加...

    Cobub 评论0 收藏0

发表评论

0条评论

legendmohe

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<