一、树的相关概念

1.基本概念

子树

一个子树由一个节点和它的后代构成。

节点的度

节点所拥有的子树的个数。

树的度

树中各节点度的最大值

节点的深度

节点的深度等于祖先节点的数量

树的高度

树的高度等于所有节点深度的最大值

森林

若干课互不相交的树的集合。任何一棵树,删去根节点就变成了森林。

2. 二叉树

二叉树的定义

(1)二叉树中每个节点的度不大于2

(2)二叉树是有序的,其子树有左右之分,其次序不能随意颠倒

二叉树的性质

  • 第k层上最多有2^(k-1)个节点
  • 深度为k的二叉树最多有 2^k-1 个节点

3. 几种特殊的二叉树

满二叉树

深度为k且有2^k-1个节点的二叉树

完全二叉树

有n个节点的二叉树,当且仅当其每个节点按从上到下、从左至右的顺序进行编号,其编号与满二叉树中1至n的节点编号一一对应

  • 有n个节点的完全二叉树中最后一个有子节点的节点的序号:Math.floor(n/2-1)

二叉搜索树

二叉树的一种,但是它只允许左子节点存储比父节点小的值,右子节点存储比父节点大的值。这是本文要研究的数据结构

2.二叉搜索树及相关方法的js实现代码

function BinarySearchTree() {

  //Node类表示树中的节点
const Node = function(key) {
this.key = key;
this.left = null;
this.right = null;
}; // 变量root表示根节点
let root = null; //向树中插入一个节点
this.insert = function(key) {
const newNode = new Node(key);
const 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);
}
}
}
if (root === null) {
root = newNode;
} else {
insertNode(root, newNode);
}
}; //先序遍历:根左右
this.preOrderTraverse = function(callback) {
const preOrderTraverseNode = function(node, callback) {
if (node !== null) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
preOrderTraverseNode(root, callback) }; //中序遍历: 左根右
this.inOrderTraverse = function(callback) {
const inOrderTraverseNode = function (node, callback) {
if (node !== null) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
inOrderTraverseNode(root, callback);
}; //后序遍历:左右根
this.postOrderTraverse = function(callback) {
const postOrderTraverseNode = function(node, callback) {
if (node !== null) {
postOrderTraverseNode(node.left, callback);
postOrderTraverseNode(node.right, callback);
callback(node.key);
}
};
postOrderTraverseNode(root, callback);
}; //寻找树中的最小值,并返回这个最小值
this.min = function () {
const minNode = function(node) {
if (node) {
while (node.left !== null) {
node = node.left;
}
return node.key
}
return null;
};
return minNode(root);
}; //寻找树中的最大值,病返回这个最大值
this.max = function() {
const maxNode = function(node) {
if (node) {
while (node.right !== null) {
node = node.right;
}
return node.key;
}
return null;
};
return maxNode(root);
} //寻找树中是否存在一个特定值,存在返回true,不存在返回false
this.search = function(key) {
const searchNode = function(node, key) {
if (node === null) {
return false;
} if (key < node.key) {
return searchNode(node.left, key);
} else if (key > node.key) {
return searchNode(node.right, key);
} else {
return true;
}
} return searchNode(root, key);
}; //从树中移除一个节点
this.remove = function(key) {
const findMinNode = function(node) { //与方法min中的minNode不同的是,minNode返回node.key,它返回node本身
while (node.left !== null) {
node = node.left;
}
return node;
};
const removeNode = function(node, key) {
if (node === null) {
return null;
} if (key < node.key) { //这种情况需要更新node.left,然后返回更新了node.left的新的node
node.left = removeNode(node.left, key);
return node;
} else if (key > node.key) { //这种情况需要更新node.right,然后返回更新了node.right的新的node
node.right = removeNode(node.right, key);
return node;
} else { //这种情况需要更新node.key或者其他更新手段(包括直接将node变为null, 或更新node.right),返回的也是更新后的node //情况1,被移除的是叶子节点
if (node.left === null && node.right === null) {
node = null;
return node;
} //情况2,被移除的是只有一个子节点的节点
if (node.left === null) { //只有右子节点
node = node.right;
return node;
} else if (node.right === null) {//只有左子节点
node = node.left;
return node;
} //情况3, 被移除的是有两个子节点的节点
const aux = findMinNode(node.right);//找到子树中的最小节点,它肯定是一个叶子节点
node.key = aux.key;//更新node的key //node.left不变
//node.right要删除上述aux节点
node.right = removeNode(node.right, aux.key);//更新node.right,这里其实是移除了一个以node.right为root的树的叶子节点 return node;
}
}; root = removeNode(root, key);
};
}

参考资料

-《学习JavaScript数据结构和算法》Chapter8

-《数据结构(C语言版)》Chapter6

数据结构-二叉搜索树的js实现的更多相关文章

  1. 数据结构-二叉搜索树(BST binary search tree)

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来 ...

  2. 数据结构☞二叉搜索树BST

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...

  3. 基本数据结构 —— 二叉搜索树(C++实现)

    目录 什么是二叉搜索树 二叉搜索树如何储存数值 二叉搜索树的操作 插入一个数值 查询是否包含某个数值 删除某个数值 测试代码 参考资料 什么是二叉搜索树 二叉搜索树(英语:Binary Search ...

  4. 数据结构---二叉搜索树BST实现

    1. 二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一 ...

  5. 数据结构-二叉搜索树和二叉树排序算法(python实现)

    今天我们要介绍的是一种特殊的二叉树--二叉搜索树,同时我们也会讲到一种排序算法--二叉树排序算法.这两者之间有什么联系呢,我们一起来看一下吧. 开始之前呢,我们先来介绍一下如何创建一颗二叉搜索树. 假 ...

  6. 数据结构 - 二叉搜索树封装 C++

    二叉搜索树封装代码 #pragma once #include <iostream> using namespace std; template<class T>class T ...

  7. Java数据结构——二叉搜索树

    定义二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若 ...

  8. 数据结构——二叉搜索树(Binary Search Tree)

    二叉树(Binary Tree)的基础下 每个父节点下 左节点小,右节点大. 节点的插入: 若root==NULL则root=newnode 否则不断与节点值比较,较小则向左比较,较大则向右比较. 完 ...

  9. 数据结构-二叉搜索树Java实现

    1,Node.java 生成基础二叉树的结构 package com.cnblogs.mufasa.searchTree; /** * 节点配置父+左+右 */ public class Node{ ...

随机推荐

  1. 九度OJ 1250:矩阵变换 (矩阵运算)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:95 解决:47 题目描述: 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一, 现给出一正数矩 ...

  2. visual studio2017 无法添加引用 未能加载包ReferenceManagerPackage not such interface support 解决方法

    安装完visual studio 2017 后添加引用总是提示 未能加载包ReferenceManagerPackage, 这个问题困扰了两天,直到在网上看到了下面这一段 I just got thi ...

  3. Django之CURD插件

    什么是CURD? CURD顾名思义就是create,update,rearch,delete(所谓的增删改查). 当我们接到一个项目的时候,夸夸夸的就写完表结构,然后就一直写增删改查,增删改查,写了一 ...

  4. ABAP--关于字符串String到XString XString to String转换代码

    转自http://guanhuaing.iteye.com/blog/1498891 代码如下 report zrich_0001. data: s type string, h(1) type x, ...

  5. jQuery悬浮焦点图宽屏

    在线演示 本地下载

  6. Luogu-4410 [HNOI2009]无归岛

    裸的仙人掌最大独立子集,结果一个zz的错误让我调了好久... \(-inf\)开始设为\(0x7fffffff\)结果\(A_i\)有负数一加就炸了 #include<cstdio> #i ...

  7. Elasticsearch核心知识大纲脑图

  8. 一张图理解is_nll isset empty

    isset 判断变量是否已存在,如果变量存在则返回 TRUE,否则返回 FALSE. empty 判断变量是否为空,如果变量是非空 或非零 的值,则 empty() 返回 FALSE.换句话说,&qu ...

  9. 内存表 ClientDataSet CreateDataSet

    unit Form_Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, F ...

  10. C++(九)— 虚函数、纯虚函数、虚析构函数

    1.虚函数 原因:通过指针调用成员函数时,只能访问到基类的同名成员函数.在同名覆盖现象中,通过某个类的对象(指针及引用)调用同名函数,编译器会将该调用静态联编到该类的同名函数,也就是说,通过基类对象指 ...