JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解

JS中的算法与数据结构:二叉查找树(Binary Sort Tree)

什么是二叉查找树

二叉查找树(Binary Sort Tree),又称二叉搜索树或二叉排序树,是一种特殊的二叉树结构。它具有以下性质:

  • 每个结点最多只有两个子结点。
  • 左子树中的所有结点的值均小于它的根结点的值。
  • 右子树中的所有结点的值均大于它的根结点的值。
  • 没有相同节点值出现

因为具备以上性质,所以可以对其进行查找、插入、删除等操作,时间复杂度为 O(log n)。

实现过程

插入节点

向二叉查找树中插入一个节点,需要从二叉树的根节点开始查找。此时,有以下两种情况:

  1. 如果树为空,直接将该节点作为根节点。
  2. 如果该节点的值大于当前节点的值,则向右子树查找。如果右子树为空,则将该节点作为当前节点的右子节点。如果右子树不为空,继续查找。
  3. 如果该节点的值小于当前节点的值,则向左子树查找。如果左子树为空,则将该节点作为当前节点的左子节点。如果左子树不为空,继续查找。
class BinarySortTree {
  constructor() {
    this.root = null; // 初始化根节点为空
  }

  // 插入节点
  insert(key) {
    const newNode = new Node(key); // 创建一个新节点
    if (this.root === null) { // 树为空时,直接将该节点作为根节点
      this.root = newNode;
    } else {
      this.insertNode(this.root, newNode);
    }
  }

  // 插入节点-辅助方法
  insertNode(root, newNode) {
    if (newNode.key > root.key) { // 如果节点值大于当前节点的值
      if (root.right === null) { // 如果右子树为空,则将该节点作为当前节点的右子节点
        root.right = newNode;
      } else { // 如果右子树不为空,继续查找
        this.insertNode(root.right, newNode);
      }
    } else { // 如果节点值小于当前节点的值
      if (root.left === null) { // 如果左子树为空,则将该节点作为当前节点的左子节点
        root.left = newNode;
      } else { // 如果左子树不为空,继续查找
        this.insertNode(root.left, newNode);
      }
    }
  }
}

class Node {
  constructor(key) {
    this.key = key;
    this.left = null;
    this.right = null;
  }
}

查找节点

从根节点开始查找,依次比较节点值和要查找的值。如果相等,则返回该节点。如果当前节点的值大于要查找的值,则向左子树查找。如果当前节点的值小于要查找的值,则向右子树查找。如果找不到,则返回 null。

// 查找节点
search(key) {
  return this.searchNode(this.root, key);
}

// 查找节点-辅助方法
searchNode(root, key) {
  if (root === null) { // 如果树为空或者已经遍历过整个树,则返回null
    return null;
  } else if (root.key === key) { // 如果当前节点的值等于查找的值,则返回该节点
    return root;
  } else if (root.key > key) { // 如果当前节点的值大于查找的值,则向左子树查找
    return this.searchNode(root.left, key);
  } else { // 如果当前节点的值小于查找的值,则向右子树查找
    return this.searchNode(root.right, key);
  }
}

删除节点

删除节点需要注意以下三种情况:

  1. 节点为叶子节点,即没有子节点。此时,直接删除该节点即可。
  2. 节点只有一个子节点。此时,将该节点的子节点替换该节点即可。
  3. 节点有两个子节点。此时,将该节点的后继节点(即右子树的最小值)替换该节点。
// 删除节点
remove(key) {
  this.root = this.removeNode(this.root, key);
}

// 删除节点-辅助方法
removeNode(root, key) {
  if (root === null) { // 如果树为空
    return null;
  } else if (key < root.key) { // 如果当前节点的值大于要删除的值,则向左子树查找
    root.left = this.removeNode(root.left, key);
    return root;
  } else if (key > root.key) { // 如果当前节点的值小于要删除的值,则向右子树查找
    root.right = this.removeNode(root.right, key);
    return root;
  } else { // 如果当前节点的值等于要删除的值

    // 第一种情况:节点为叶子节点
    if (root.left === null && root.right === null) {
      root = null;
      return root;
    }

    // 第二种情况:节点只有一个子节点
    if (root.left === null) {
      root = root.right;
      return root;
    } else if (root.right === null) {
      root = root.left;
      return root;
    }

    // 第三种情况:节点有两个子节点
    const aux = this.findMinNode(root.right); // 获取右子树的最小节点
    root.key = aux.key; // 将当前节点的值替换为后继节点的值
    root.right = this.removeNode(root.right, aux.key); // 删除后继节点
    return root;
  }
}

// 查找最小节点
findMinNode(node) {
  while (node.left !== null) {
    node = node.left;
  }
  return node;
}

示例

const bst = new BinarySortTree();

bst.insert(11);
bst.insert(7);
bst.insert(15);
bst.insert(5);
bst.insert(3);
bst.insert(9);
bst.insert(8);
bst.insert(10);
bst.insert(13);
bst.insert(12);
bst.insert(14);
bst.insert(20);
bst.insert(18);
bst.insert(25);

console.log(bst.search(9)); // 返回: Node { key: 9, left: Node {...}, right: Node {...} }
console.log(bst.search(19)); // 返回: null

bst.remove(5);
console.log(bst.root.left.left); // 返回: Node { key: 3, left: null, right: null }

以上代码演示了一个二叉查找树,其中包括节点的插入、查找和删除操作。其中,演示了一个查找成功的情况和一个查找失败的情况,以及一个删除节点的操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • js实现无限层级树形数据结构(创新算法)

    要实现无限层级树形数据结构,可以使用递归算法来解决。以下是该过程的详细攻略: 步骤1:准备数据 为了演示无限层级树形结构,我们需要准备一组具有父子关系的数据。数据可以是任何格式,例如在子对象节点下添加一个名为children的数组即可。 例如,假设我们有以下数据: const data = [ { id: 1, name: "Node 1&quot…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构与算法之二叉树遍历算法详解【先序、中序、后序】

    JavaScript数据结构与算法之二叉树遍历算法详解 什么是二叉树 二叉树是一种每个节点最多只有两个子节点的树结构,可以用来组织数据、搜索、排序等。 二叉树的遍历 遍历是指按照一定次序访问二叉树中的所有节点。常见的二叉树遍历有三种方式:先序遍历、中序遍历、后序遍历。以下分别对它们进行详细讲解。 前序遍历 前序遍历是指先访问节点本身,然后再遍历其左子树和右子…

    数据结构 2023年5月17日
    00
  • Javascript数据结构与算法之列表详解

    Javascript数据结构与算法之列表详解 简介 本文旨在讲解Javascript中数据结构和算法的列表。 列表定义和实现 列表是一组有序的数据,每个列表中的数据项称为元素。在Javascript中,列表可以用数组来实现。数组的好处是它能够存储任意类型的数据,而且可以根据需要动态地调整数组的大小。下面是一个创建列表的基本模板: function List(…

    数据结构 2023年5月17日
    00
  • Java 超详细图解集合框架的数据结构

    下面是完整攻略: Java 超详细图解集合框架的数据结构 简介 集合框架是Java中最基础的数据结构之一,是大部分Java程序员必须掌握的基础知识。这个框架提供了常用的数据结构和算法,包括List、Set、Map等等。本文将带领您从数据结构的角度详细解析Java集合框架中的各种数据结构,让您能够清晰地掌握它们的特点和使用方法。 数据结构 Java集合框架中的…

    数据结构 2023年5月17日
    00
  • C语言数据结构之图书借阅系统

    C语言数据结构之图书借阅系统是一款基于C语言的软件,主要用于管理图书馆的借阅信息,并提供图书查询、借阅、归还等功能。本文将介绍图书借阅系统的完整攻略。 设计思路 图书借阅系统的设计主要包括三个阶段:系统设计、数据结构设计和用户接口设计。 系统设计 系统设计是构建整个系统的重要阶段,需要确定系统的功能需求、模块划分和流程控制。本系统的主要功能包括: 图书查询:…

    数据结构 2023年5月17日
    00
  • C++数据结构链表基本操作示例过程

    C++数据结构链表基本操作示例过程 链表是一种重要的数据结构,C++中链表的操作是非常常见的,下面我将详细介绍C++中链表的基本操作,包括创建链表、插入节点、删除节点和遍历链表等。 创建链表 首先,需要创建一个链表结构体,并定义节点类型struct Node,其中包含元素数据及下一个节点的指针。 struct Node { int data; Node* n…

    数据结构 2023年5月17日
    00
  • 数据结构与算法之并查集(不相交集合)

    下面是详细的内容讲解。 数据结构与算法之并查集(不相交集合) 什么是并查集? 并查集,也叫不相交集合,是一种树形的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常是在使用 Kruskal 算法或者 Prim 算法来求解最小生成树(Minimum Spanning Tree)时用到的一种数据结构。 并查集的基本操作 Make…

    数据结构 2023年5月17日
    00
  • C语言数据结构 快速排序实例详解

    C语言数据结构 快速排序实例详解 什么是快速排序? 快速排序(Quicksort)是一种采用分治法(Divide and Conquer)的排序算法,通过将一个大问题逐步分解为小问题来解决的一种工具。 快速排序是一个比较快的排序算法,在平均状况下,排序n个项目要 O(n log n) 次比较,最坏情况下需要O(n^2)次比较,但这种状况并不常见。 快速排序算…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部