二叉树是一种数据结构。其特点是:

1.由一系列节点组成,具有层级结构。每个节点的特性包含有节点值、关系指针。节点之间存在对应关系。

2.树中存在一个没有父节点的节点,叫做根节点。树的末尾存在一系列没有子节点的节点,称为叶子节点。其他可以叫做中间节点。

3.树的根节点位于第一层,层级数越大,节点位置越深,层级数也叫做树高。

排序二叉树为二叉树的一种类型,其特点是:

1.节点分为左右子树。

2.在不为空的情况下,左子树子节点的值都小于父节点的值。

3.在不为空的情况下,右子树子节点的值都大于父节点的值。

4.每个节点的左右子树都按照上述规则排序。

如图:

(打错字了..)

js代码来实现上述数据结构:

1.节点用对象来描述,节点特性用对象属性来描述。

  1. class Node {
  2. constructor(key) {
  3. this.key = key;// 节点值
  4. this.left = null;// 左指针
  5. this.right = null;// 右指针
  6. }
  7. }

2.二叉树结构用对象来描述。

  1. // 二叉树
  2. class BinaryTree {
  3. constructor() {
  4. this.root = null;// 根节点
  5. }
  6. insert(key) {// api--插入
  7. const newNode = new Node(key);
  8. if (this.root === null) {// 设置根节点
  9. this.root = newNode;
  10. }
  11. method.insertNode(this.root, newNode);
  12. }
  13. }

相关方法:

  1. // method
  2. method = {
  3. insertNode(root, newNode) {
  4. if (newNode.key < root.key) {// 进入左子树
  5. if (root.left === null) {// 左子树为空
  6. root.left = newNode;
  7. } else {// 左子树已存在
  8. method.insertNode(root.left, newNode);
  9. }
  10. } else if (newNode.key > root.key) {// 进入右子树
  11. if (root.right === null) {// 右子树为空
  12. root.right = newNode;
  13. } else {// 右子树已存在
  14. method.insertNode(root.right, newNode);
  15. }
  16. }
  17. }
  18. };

具体用法:

  1. // 实例化二叉树
  2. const binaryTree = new BinaryTree();
  3.  
  4. // key值
  5. const keys = [, , , , , , ];
  6.  
  7. // 生成排序二叉树
  8. keys.forEach(key => binaryTree.insert(key));

结果:

排序二叉树的遍历:

一、中序遍历

(1)以上图为例,中序遍历顺序为: 5 - 8 - 12 - 15 - 19 - 24 - 45。

(2)总是先遍历左子树,然后访问根节点,接着遍历右子树。

代码实现:

  1. class BinaryTree {
  2. ...
  3. // callback为访问节点时执行的操作
  4. inorderTraversal(callback) {// api--中序遍历
  5. method.inorderTraversalNode(this.root, callback);
  6. }
  7. }
  8.  
  9. method = {
  10. ...
  11.  
  12. inorderTraversalNode(node, callback) {
  13. if (node) {// 当前节点
  14. method.inorderTraversalNode(node.left, callback);// 遍历左子树
  15. callback(node);// 访问节点
  16. method.inorderTraversalNode(node.right, callback);// 遍历右子树
  17. }
  18. },
  19. };
  20.  
  21. // 中序遍历
  22. binaryTree.inorderTraversal(node => console.log(node.key));
  1. // key值
  2. const keys = [19, 8, 15, 24, 45, 12, 5];

输入结果:5 - 8 - 12 - 15 - 19 - 24 - 45

二、前序遍历

(1)以上图为例,前序遍历顺序为: 19 - 8 - 5 - 15  - 12 - 24 - 45。

(2)总是先访问根节点,然后遍历左子树,接着遍历右子树。

代码实现:

  1. class BinaryTree {
  2. ...
  3. preOrderTraversal(callback) {// api--前序遍历
  4. method.preOrderTraversalNode(this.root, callback);
  5. }
  6. }
  7.  
  8. method = {
  9. ...
  10. preOrderTraversalNode(node, callback) {
  11. if (node) {// 当前节点
  12. callback(node);// 访问节点
  13. method.preOrderTraversalNode(node.left, callback);// 遍历左子树
  14. method.preOrderTraversalNode(node.right, callback);// 遍历右子树
  15. }
  16. }
  17. };
  18.  
  19. // 前序遍历
  20. binaryTree.preOrderTraversal(node => console.log(node.key));
  1. // key值
  2. const keys = [19, 8, 15, 24, 45, 12, 5];

输入结果:19 - 8 - 5 - 15  - 12 - 24 - 45

三、后序遍历

(1)以上图为例,后序遍历顺序为: 5 - 12 - 15 - 8  - 45 - 24 - 19。

(2)先遍历左子树,接着遍历右子树,最后访问根节点。

代码实现:

  1. class BinaryTree {
  2. ...
  3. postOrderTraversal(callback) {// api--后序遍历
  4. method.postOrderTraversalNode(this.root, callback);
  5. }
  6. }
  7.  
  8. method = {
  9. ...
  10. postOrderTraversalNode(node, callback) {
  11. if (node) {// 当前节点
  12. method.postOrderTraversalNode(node.left, callback);// 遍历左子树
  13. method.postOrderTraversalNode(node.right, callback);// 遍历右子树
  14. callback(node);// 访问节点
  15. }
  16. }
  17. };
  18.  
  19. // 后序遍历
  20. binaryTree.postOrderTraversal(node => console.log(node.key));
  1. // key值
  2. const keys = [19, 8, 15, 24, 45, 12, 5];

输入结果:5 - 12 - 15 - 8  - 45 - 24 - 19

排序二叉树的查找:

(1)查找最大值。根据排序二叉树的特点,右子树的值都大于父节点的值。只需要进入节点的右子树查找,当某个节点的右子树为空时,该节点就是最大值节点。

代码实现:

  1. class BinaryTree {
  2. ...
  3. max() {
  4. return method.maxNode(this.root);
  5. }
  6. }
  7.  
  8. method = {
  9. ...
  10. maxNode(node) {
  11. if (node) {
  12. while(node.right !== null) {// 右子树不为空时
  13. node = node.right;
  14. }
  15. return node.key;
  16. }
  17. return null;
  18. }
  19. };
  1. // key值
  2. const keys = [19, 8, 15, 24, 45, 12, 5];

结果:

(2)查找最小值。根据排序二叉树的特点,左子树的值都小于父节点的值。只需要进入节点的左子树查找,当某个节点的左子树为空时,该节点就是最小值节点。

代码实现:

  1. 1 class BinaryTree {
  2. 2 ...
  3. 3 min() {
  4. 4 return method.minNode(this.root);
  5. 5 }
  6. 6 }
  7. 7
  8. 8 method = {
  9. 9 ...
  10. 10 minNode(node) {
  11. 11 if (node) {
  12. 12 while(node.left!== null) {// 左子树不为空时
  13. 13 node = node.left;
  14. 14 }
  15. 15 return node.key;
  16. 16 }
  17. 17 return null;
  18. 18 }
  19. 19 };
  1. // key值
  2. const keys = [19, 8, 15, 24, 45, 12, 5];

结果:

(3)查找给定值。在排序二叉树中查找有没有节点对应的值与给定值相同。

根据排序二叉树的特点,比较给定值与节点值,小于时进入节点左子树。大于时进入节点右子树。等于时返回真。层层对比,最后如果子树为空,则表示没有找到。

代码实现:

  1. class BinaryTree {
  2. ...
  3. search(key) {
  4. return method.searchNode(this.root, key);
  5. }
  6. }
  7.  
  8. method = {
  9. ...
  10. searchNode(node, key) {
  11. if (node === null) {// 没有找到
  12. return false;
  13. }
  14. if (key < node.key) {// 进入左子树
  15. return method.searchNode(node.left, key);
  16. } else if (key > node.key) {// 进入右子树
  17. return method.searchNode(node.right, key);
  18. } else {// 找到了
  19. return true;
  20. }
  21. }
  22. };
  1. // key值
  2. const keys = [19, 8, 15, 24, 45, 12, 5];

结果:

排序二叉树的删除:

当删除的节点为叶子节点时,直接把叶子节点设置成空。如图:删除值为5的节点。

原:

现:

当删除的节点存在左子树时,把父节点的关系指针直接指向左子树。如图:删除值为15的节点。存在右子树时同理。

原:

现:

当节点存在左右子树时,先去右子树里找到最小值,然后用最小值替换节点值,最后进入右子树删除最小值对应的节点。如图:删除值为8的节点。

原:

现:

代码实现:

  1. class BinaryTree {
  2. ...
  3. remove(key) {
  4. this.root = method.removeNode(this.root, key);
  5. }
  6. }
  7.  
  8. method = {
  9. ...
  10. removeNode(node, key) {
  11. if(node === null) {// 没有找到值对应的节点
  12. return null;
  13. }
  14. if (key < node.key) {// 给定值小于当前节点值
  15. node.left = method.removeNode(node.left, key);
  16. return node;
  17. } else if (key > node.key) {// 给定值大于当前节点值
  18. node.right = method.removeNode(node.right, key);
  19. return node;
  20. } else {// 找到给定值对应的节点
  21. if (node.left === null && node.right === null) {// 节点为叶子节点
  22. node = null;
  23. return node;
  24. }
  25.  
  26. if (node.left === null) {// 节点存在右子树
  27. node = node.right;
  28. return node;
  29. } else if (node.right === null) {// 节点存在左子树
  30. node = node.left;
  31. return node;
  32. }
  33.  
  34. // 节点存在左右子树时,先去右子树里找到最小值,然后用最小值替换节点值,最后进入右子树删除最小值对应的节点。
  35. const minKey = method.minNode(node.right);
  36. node.key = minKey;
  37. method.removeNode(node.right, minKey);
  38. return node;
  39. }
  40. }
  41. };

结果:

累死我了。。。

javascript/js实现 排序二叉树数据结构 学习随笔的更多相关文章

  1. c数据结构学习随笔

    #include <stdio.h> #include <stdlib.h> #include "PublicDS.h" #include<Windo ...

  2. 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

    树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n ...

  3. JavaScript ES6 数组新方法 学习随笔

    JavaScript ES6 数组新方法 学习随笔 新建数组 var arr = [1, 2, 2, 3, 4] includes 方法 includes 查找数组有无该参数 有返回true var ...

  4. JavaScript实现排序二叉树的相关算法

    1.创建排序二叉树的构造函数 /** * 创建排序二叉树的构造函数 * @param valArr 排序二叉树中节点的值 * @constructor */ function BinaryTree(v ...

  5. 数据结构----二叉树Tree和排序二叉树

    二叉树 节点定义 class Node(object): def __init__(self, item): self.item = item self.left = None self.right ...

  6. 用js来实现那些数据结构及算法—目录

    首先,有一点要声明,下面所有文章的所有内容的代码,都不是我一个人独立完成的,它们来自于一本叫做<学习JavaScript数据结构和算法>(第二版),人民邮电出版社出版的这本书.github ...

  7. c++(排序二叉树)

    前面我们讲过双向链表的数据结构.每一个循环节点有两个指针,一个指向前面一个节点,一个指向后继节点,这样所有的节点像一颗颗珍珠一样被一根线穿在了一起.然而今天我们讨论的数据结构却有一点不同,它有三个节点 ...

  8. 用js来实现那些数据结构—目录

    首先,有一点要声明,下面所有文章的所有内容的代码,都不是我一个人独立完成的,它们来自于一本叫做<学习JavaScript数据结构和算法>(第二版),人民邮电出版社出版的这本书.github ...

  9. 2、JavaScript 基础二 (从零学习JavaScript)

     11.强制转换 强制转换主要指使用Number.String和Boolean三个构造函数,手动将各种类型的值,转换成数字.字符串或者布尔值. 1>Number强制转换 参数为原始类型值的转换规 ...

随机推荐

  1. shell编程系列26--大型脚本工具开发实战

    shell编程系列26--大型脚本工具开发实战 大型脚本工具开发实战 拆分脚本功能,抽象函数 .function get_all_group 返回进程组列表字符串 .function get_all_ ...

  2. (待续)【转载】 DeepMind发Nature子刊:通过元强化学习重新理解多巴胺

    原文地址: http://www.dataguru.cn/article-13548-1.html -------------------------------------------------- ...

  3. 003-结构型-04-外观模式(Facade)

    一.概述 Facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种.Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面.这个一致的简单的界面被称作fa ...

  4. org/apache/curator/RetryPolicy at com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter.connect(CuratorZookeeperTransporter.java:26)

    使用dubbo服务,启动项目报错: org/apache/curator/RetryPolicy at com.alibaba.dubbo.remoting.zookeeper.curator.Cur ...

  5. 一台服务器部署多台tomcat

    如题,多个项目部署在一台服务器.减少容错性,觉得分开部署,这样一个tomcat挂了不会影响另一个项目.看配置和应用大小决定数量,一般四五个没问题,也有单台服务器部署8个tomcat稳定运行的. 下面记 ...

  6. 基于Source Insight_Scan的C/C++静态代码检查工具安装说明

    基于Source Insight_Scan的C/C++静态代码检查工具安装说明   本文链接:https://blog.csdn.net/M19930517/article/details/79977 ...

  7. xps转换为pdf

    https://www.cnblogs.com/zeoy/archive/2013/01/09/2852941.html https://blog.csdn.net/jafucong/article/ ...

  8. spring添加事物

    <context:component-scan base-package="com.zlkj" > <context:include-filter type=&q ...

  9. TCP/IP学习笔记11--无线通信: 无线通信的种类, 点对点通信协议

    IEEE802委员会主要指定了以下几种分类: PAN: personal aera network;  LAN: local area network; WAN: wide aera network ...

  10. LeetCode 279. 完全平方数(Perfect Squares) 7

    279. 完全平方数 279. Perfect Squares 题目描述 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n.你需要让组成和的完全平方数 ...