[Estructura y algoritmo de datos JS] Métodos comunes de árbol de búsqueda binaria

Tabla de contenido

1. Introducir la encapsulación de la estructura del árbol binario

Dos, inserte el inserto (clave)

En tercer lugar, el método transversal del árbol binario.

1. Travesía de primer orden

2. Recorrido en orden

3. Recorrido posterior al pedido

Cuarto, el árbol de búsqueda binaria encuentra el mejor valor

Cinco, árbol de búsqueda binaria para encontrar una clave

Seis, el nodo de eliminación del árbol de búsqueda binaria

Siete, código completo


1. Introducir la encapsulación de la estructura del árbol binario

function BinarySearchTree(){

      // 新结点创建的构造函数
      function Node(key){
        this.key = key;
        this.lchild = null;
        this.rchild = null;
      }

      // 保存根的属性
      this.root = null;

      // 创建关于二叉搜索树的相关操作方法

}

Dos, inserte el inserto (clave)

Ideas:

Crear método de inserción

    1. Crea un nuevo nodo

    2. Determine si es un árbol vacío.
         2.1 Si es un árbol vacío, deje que el atributo de la raíz apunte al nuevo nodo.
         2.2 Si no es un árbol no vacío, busque una ubicación adecuada para insertar

Luego cree un método para uso interno insertNode ()
. 1, compare el nuevo nodo y el valor del tamaño del nodo
       1.1 si el valor del nuevo nodo que los valores del nodo de la pequeña
               inserción de la comparación del nodo del subárbol derecho vacío, no hay para continuar vaciar la comparación derecha
       1.2 Si el valor del nuevo nodo que el valor del nodo gran
                inserción comparar el subárbol izquierdo del nodo está vacío, no continúa vacío a la comparación izquierda

Para el siguiente árbol, si desea insertar el nodo 20, realice los siguientes pasos:

Código:

      // 插入元素,给用户使用
      BinarySearchTree.prototype.insert = function(key){
        // 1、创建新结点
        var newNode = new Node(key);

        // 2、判断是否为空树
        // 2.1如果是空树,则让根的属性指向新结点
        if (this.root == null){
          this.root = newNode;
        }else{// 2.2如果不是非空树,则寻找合适的位置插入
          this.insertNode(this.root, newNode);
        }
      }

      // 用于内部使用
      BinarySearchTree.prototype.insertNode = function(node, newNode){

        // 1、比较结点与新结点的值大小
        // 1.1如果结点的值比新结点的值小
        if (node.key < newNode.key) {
          // 比较结点的右子树为空时插入,不为空时继续往下比较
          if (node.rchild == null) {
            node.rchild = newNode;
          }else{
            this.insetNode(node.rchild, newNode);
          }
        }else{ // 1.2 如果结点的值比新结点的值大
          // 比较结点的左子树为空时插入,不为空时继续往下比较
          if (node.lchild == null) {
            node.lchild = newNode;
          }else{
            this.insertNode(node.lchild, newNode);
          }
        }
      }

Prueba de código

    // 测试
    // 1、创建BinarySearchTree
    var bst = new BinarySearchTree();

    // 2、插入数据
    bst.insert(18);
    bst.insert(4);
    bst.insert(2);
    bst.insert(7);
    bst.insert(30);
    bst.insert(24);
    bst.insert(20);

    // 3、输出结构
    console.log(bst);

          ——》

En tercer lugar, el método transversal del árbol binario.

El recorrido del árbol de búsqueda binario es el recorrido del árbol binario. Si desea recorrer cada nodo, debe hacerlo en un orden determinado.

Hay tres métodos comunes para árboles binarios:

  • Recorrido de preorden
  • Recorrido en orden
  • Recorrido posterior al pedido

Otro recorrido poco común es el recorrido jerárquico, que consiste en recorrer de arriba a abajo de izquierda a derecha de acuerdo con cada nivel del árbol.

1. Travesía de primer orden

Definición de operación:

Si el árbol binario está vacío, no hay operación; de lo contrario

(1) Visite el nodo raíz;

(2) Primero atraviese el subárbol izquierdo;

(3) Primero atraviese el subárbol derecho.

                             

Código:

      // 先序遍历
      BinarySearchTree.prototype.preOrderTraversal = function(fun){
        // 让preOrderTraversalNode去实现递归操作
        this.preOrderTraversalNode(this.root, fun)
      }

      // 内部使用
      BinarySearchTree.prototype.preOrderTraversalNode = function(node, fun){

        if (node) {
          // 1、打印当前结点
          fun(node.key);

          // 2、遍历所有的左子树;
          this.preOrderTraversalNode(node.lchild, fun);

          // 3、遍历所有的右子树。
          this.preOrderTraversalNode(node.rchild, fun);
        }
      }

Código de prueba

// 测试
    // 1、创建BinarySearchTree
    var bst = new BinarySearchTree();

    // 2、插入数据
    bst.insert(18);
    bst.insert(4);
    bst.insert(2);
    bst.insert(7);
    bst.insert(30);
    bst.insert(24);
    bst.insert(20);

    // 3、先序遍历
    var result = '';
    bst.preOrderTraversal(function (key){
      result += key + ' ';
    })
    console.log(result); //18 4 2 7 30 24 20 

2. Recorrido en orden

Definición de operación:

Si el árbol binario está vacío, no hay operación; de lo contrario

(1) Para atravesar el subárbol izquierdo;

(2) Visite el nodo raíz;

(3) Para atravesar el subárbol derecho.

                             

Código:

      // 中序遍历
      BinarySearchTree.prototype.midOrderTraversal = function(fun){
        // 让midOrderTraversalNode去实现递归操作
        this.midOrderTraversal(this.root, fun)
      }

      // 内部使用
      BinarySearchTree.prototype.midOrderTraversalNode = function(node, fun){

        if (node) {

          // 1、遍历所有的左子树;
          this.midOrderTraversalNode(node.lchild, fun);

          // 2、打印当前结点
          fun(node.key);

          // 3、遍历所有的右子树。
          this.midOrderTraversalNode(node.rchild, fun);
        }
      }

Código de prueba

// 测试
    // 1、创建BinarySearchTree
    var bst = new BinarySearchTree();

    // 2、插入数据
    bst.insert(18);
    bst.insert(4);
    bst.insert(2);
    bst.insert(7);
    bst.insert(30);
    bst.insert(24);
    bst.insert(20);

    // 3、中序遍历
    var result = '';
    bst.midOrderTraversal(function (key){
      result += key + ' ';
    })
    console.log(result); //2 4 7 18 20 24 30 

3. Recorrido posterior al pedido

Definición de operación:

Si el árbol binario está vacío, no hay operación; de lo contrario

(1) Atraviesa el subárbol izquierdo en orden posterior;

(2) Atraviesa el subárbol derecho en orden posterior.

(3) Visite el nodo raíz;

                             

Código:

      // 后序遍历
      BinarySearchTree.prototype.postOrderTraversal = function(fun){
        // 让postOrderTraversalNode去实现递归操作
        this.postOrderTraversalNode(this.root, fun)
      }

      // 内部使用
      BinarySearchTree.prototype.postOrderTraversalNode = function(node, fun){

        if (node) {

          // 1、遍历所有的左子树;
          this.postOrderTraversalNode(node.lchild, fun);

          // 2、遍历所有的右子树。
          this.postOrderTraversalNode(node.rchild, fun);

          // 3、打印当前结点
          fun(node.key);
        }
      }

Código de prueba

// 测试
    // 1、创建BinarySearchTree
    var bst = new BinarySearchTree();

    // 2、插入数据
    bst.insert(18);
    bst.insert(4);
    bst.insert(2);
    bst.insert(7);
    bst.insert(30);
    bst.insert(24);
    bst.insert(20);

    // 3、先序遍历
    var result1 = '';
    bst.preOrderTraversal(function (key){
      result1 += key + ' ';
    })
    console.log(result1); //18 4 2 7 30 24 20 

    // 4、中序遍历
    var result2 = '';
    bst.midOrderTraversal(function (key){
      result2 += key + ' ';
    })
    console.log(result2); //2 4 7 18 20 24 30 


    // 5、后序遍历
    var result3 = '';
    bst.postOrderTraversal(function (key){
      result3 += key + ' ';
    })
    console.log(result3); //2 7 4 20 24 30 18 

Cuarto, el árbol de búsqueda binaria encuentra el mejor valor

Si el árbol está vacío, no hay un valor máximo,

Si el arbol no esta vacio

  • Tiene que comenzar desde el nodo raíz y encontrar el último es el valor más grande .
  • Tiene que empezar desde la raíz izquierda para encontrar el último es el valor más pequeño .

Código:

      // 最大值
      BinarySearchTree.prototype.max = function(){
        var node = this.root;

        var key = null;
        while(node){
          key = node.key;
          node = node.rchild;
        }
        return key;
      }

      // 最小值
      BinarySearchTree.prototype.min = function(){
        var node = this.root;

        var key = null;
        while(node){
          key = node.key;
          node = node.lchild;
        }
        return key;
      }

Cinco, árbol de búsqueda binaria para encontrar una clave

Encontrar la clave es muy similar a la búsqueda al insertar un elemento, aquí usamos un bucle para escribir el código.

      // 查找某个key
      BinarySearchTree.prototype.searchKey = function(key){
        var node = this.root;

        while(node != null){
          if (node.key < key) {
            node = node.rchild;
          }else if (node.key > key) { 
            node = node.lchild;
          }else{
            return true;
          }
        }
        return false;
      }

 

Seis, el nodo de eliminación del árbol de búsqueda binaria

Mencioné un punto antes que es muy complicado realizar la operación de borrado de nodos del árbol de búsqueda binaria, porque hay muchas situaciones, luego lo analizaremos poco a poco. La operación no es difícil de entender, y lo más importante es considerarlo bien. Para la estructura del árbol binario, dividimos el número de subnodos conectados por el nodo eliminado en tres casos

Caso 1: el nodo eliminado no tiene nodos secundarios (es decir, es un nodo hoja).

Caso 2: el nodo eliminado tiene un nodo hijo.

Situación 3: el nodo eliminado tiene dos nodos secundarios.

Pasos específicos:

1. Busque el nodo que desea eliminar.

  • 1.1 Definir variables y guardar información.

actual guarda el nodo raíz;

El registro principal elimina el nodo principal del nodo;

isLeftChild determina si el nodo eliminado es el nodo secundario izquierdo del nodo principal.

var current = this.root; // 保存根结点
var parent = null;   // 记录删除结点的父节点
var isLeftChild = true;   //判断删除的结点是否是该父结点的左子结点

 

  • 1.2 Busque el nodo que desee eliminar y salga si se ha encontrado el último nodo.
// 1.2 查找要删除的结点
while(current.key != key){
  parent = current;
  if (key < current.key) {
    isLeftChild = true;
    current = current.lchild;
  }else{
    isLeftChild = false;
    current = current.rchild;
  }

  // 已经找到最后一个结点还没有找到就退出
  if (current == null) return false;
}

 

2. Busque el nodo y elimine el nodo según la situación correspondiente.

  • 2.1 Caso 1: El nodo eliminado es un nodo hoja (es decir, no hay nodos secundarios).

① Si el árbol tiene solo un nodo raíz, simplemente elimínelo.

② Si el árbol tiene varios nodos y los nodos hoja se eliminan, el campo del puntero se puede dejar vacío de acuerdo con el nodo principal del nodo que se eliminará.

// 2.1删除的结点是叶子结点(即没有子结点)
if (current.lchild == null && current.rchild == null) {
  if (current == this.root) {
    this.root = null;
  } else if (isLeftChild) {
    parent.lchild = null;
  } else {
    parent.rchild = null;
  }
}

 

  • 2.2 Caso 2: El nodo eliminado tiene un nodo hijo.

① El nodo eliminado es el nodo raíz. Apunte this.root a un nodo secundario del nodo que desea eliminar.

② No se encuentra que el nodo eliminado sea el nodo raíz. Hay cuatro situaciones específicas.

else if (current.rchild == null) {
  if (current == this.root) {
    this.root = current.lchild;
  } else if (isLeftChild) {
    parent.lchild = current.lchild;
  } else {
    parent.rchild = current.lchild;
  }
} else if (current.lchild == null) {
  if (current == this.root) {
    this.root = current.rchild;
  } else if (isLeftChild) {
    parent.lchild = current.rchild;
  } else {
    parent.rchild = current.rchild;
  }
}

 

  • 2.3 Caso 3: El nodo eliminado tiene dos nodos secundarios.

Si el nodo que eliminamos tiene dos nodos secundarios, es posible que todavía haya nodos en los nodos secundarios, entonces necesitamos encontrar un nodo para reemplazar el nodo eliminado.

Podemos encontrar el que sea un poco más grande que el nodo eliminado, o el que sea un poco más pequeño que el nodo eliminado, es decir, el nodo de reemplazo más cercano al nodo eliminado.

Entonces debe:

Un poco más pequeño que el nodo eliminado debe ser el valor máximo ( predecesor ) del subárbol izquierdo del nodo eliminado .

El ligeramente más grande que el nodo eliminado debe ser el valor mínimo ( sucesor ) del subárbol derecho del nodo eliminado .

Aquí utilizamos el método de búsqueda y reemplazo posteriores de nodos.

① El nodo eliminado es el nodo raíz, apunte this.root al nodo que se reemplazará y el nodo principal del nodo reemplazado se conectará al nodo derecho.

② No se encuentra que el nodo eliminado sea el nodo raíz.

// 2.3删除的结点两个子结点
else {
  // 1、寻找后继
  var replaceNode = this.getReplaceNode(current);

  // 2、判断是否是根结点
  if (current == this.root) {
    this.root = replaceNode;
  } else if (isLeftChild) {
    parent.lchild = replaceNode;
  } else {
    parent.rchild = replaceNode;
  }

  // 3、将替代的结点的左子树  = 删除结点的左子树
  replaceNode.lchild = current.lchild;
}
// 找后继的方法
BinarySearchTree.prototype.getReplaceNode = function (delNode) {

  // 1、定义变量,来保存找到的后继
  var replaceNode = delNode; // 替代的结点
  var previous = delNode.rchild;  //删除结点的右结点
  var replaceParent = delNode;

  // 2、循环查找
  while(previous != null){
    replaceParent = replaceNode;
    replaceNode = previous;
    previous = previous.lchild;
  }

  // 3、判断找到的替换结点(后继)是否就是delNode的rchild结点,如果是则填补结点
  if (replaceNode != delNode.rchild) {
    // 后继结点必定是小于两个子结点的结点,将后继结点的父结点的左结点指向替代结点的右结点,连接操作。
    replaceParent.lchild = replaceNode.rchild;
    // 替换
    replaceNode.rchild = delNode.rchild;
  }
  return replaceNode;
}

 

Prueba de código:

    // 测试
    // 1、创建BinarySearchTree
    var bst = new BinarySearchTree();

    // 2、插入数据
    bst.insert(18);
    bst.insert(4);
    bst.insert(2);
    bst.insert(7);
    bst.insert(30);
    bst.insert(24);
    bst.insert(20);

    // 3、先序遍历
    var result1 = '';
    bst.preOrderTraversal(function (key){
      result1 += key + ' ';
    })
    console.log('先序遍历:' + result1); //18 4 2 7 30 24 20 

 

Eliminar 18

    // 6、删除操作
    // 删除根结点18
    bst.remove(18);

    // 先序遍历
    var result4 = '';
    bst.preOrderTraversal(function (key){
      result4 += key + ' ';
    })
    console.log('先序遍历为18 4 2 7 30 24 20 ,删除结点18后得到先序遍历结果:' + result4); 
    //先序遍历为18 4 2 7 30 24 20 ,删除结点18后得到先序遍历结果:20 4 2 7 30 24 

    // 插入数据
    bst.insert(26);
    bst.insert(21);
    bst.insert(25);
    bst.insert(27);

    //  先序遍历
    var result5 = '';
    bst.preOrderTraversal(function (key){
      result5 += key + ' ';
    })
    console.log('在先序为20 4 2 7 30 24 的二叉树搜索树中插入26、21、25、27,得到先序遍历结果:' + result5); 
    //在先序为20 4 2 7 30 24 的二叉树搜索树中插入26、27、28、29,得到先序遍历结果:20 4 2 7 30 24 21 26 25 27 

Eliminar 24

    // 删除结点24
    bst.remove(24);

    // 先序遍历
    var result6 = '';
    bst.preOrderTraversal(function (key){
      result6 += key + ' ';
    })
    console.log('先序遍历为20 4 2 7 30 24 21 26 25 27 ,删除结点24后得到先序遍历结果:' + result6); 
    //先序遍历为20 4 2 7 30 24 21 26 25 27 ,删除结点24后得到先序遍历结果:20 4 2 7 30 25 21 26 27 

Impresión completa

Siete, código completo

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>二叉搜索树的相关方法</title>
</head>
<body>
  <script type="text/javascript">
    function BinarySearchTree(){

      // 新结点创建的构造函数
      function Node(key){
        this.key = key;
        this.lchild = null;
        this.rchild = null;
      }

      // 保存根的属性
      this.root = null;

      // 创建关于二叉搜索树的相关操作方法

      // 插入元素,给用户使用
      BinarySearchTree.prototype.insert = function(key){
        // 1、创建新结点
        var newNode = new Node(key);

        // 2、判断是否为空树
        // 2.1如果是空树,则让根的属性指向新结点
        if (this.root == null){
          this.root = newNode;
        }else{// 2.2如果不是非空树,则寻找合适的位置插入
          this.insertNode(this.root, newNode);
        }
      }

      // 用于内部使用
      BinarySearchTree.prototype.insertNode = function(node, newNode){

        // 1、比较结点与新结点的值大小
        // 1.1如果结点的值比新结点的值小
        if (node.key < newNode.key) {
          // 比较结点的右子树为空时插入,不为空时继续往下比较
          if (node.rchild == null) {
            node.rchild = newNode;
          }else{
            this.insertNode(node.rchild, newNode);
          }
        }else{ // 1.2 如果结点的值比新结点的值大
          // 比较结点的左子树为空时插入,不为空时继续往下比较
          if (node.lchild == null) {
            node.lchild = newNode;
          }else{
            this.insertNode(node.lchild, newNode);
          }
        }
      }

      // 先序遍历
      BinarySearchTree.prototype.preOrderTraversal = function(fun){
        // 让preOrderTraversalNode去实现递归操作
        this.preOrderTraversalNode(this.root, fun)
      }

      // 内部使用
      BinarySearchTree.prototype.preOrderTraversalNode = function(node, fun){

        if (node) {
          // 1、打印当前结点
          fun(node.key);

          // 2、遍历所有的左子树;
          this.preOrderTraversalNode(node.lchild, fun);

          // 3、遍历所有的右子树。
          this.preOrderTraversalNode(node.rchild, fun);
        }
      }

      // 中序遍历
      BinarySearchTree.prototype.midOrderTraversal = function(fun){
        // 让midOrderTraversalNode去实现递归操作
        this.midOrderTraversalNode(this.root, fun)
      }

      // 内部使用
      BinarySearchTree.prototype.midOrderTraversalNode = function(node, fun){

        if (node) {

          // 1、遍历所有的左子树;
          this.midOrderTraversalNode(node.lchild, fun);

          // 2、打印当前结点
          fun(node.key);

          // 3、遍历所有的右子树。
          this.midOrderTraversalNode(node.rchild, fun);
        }
      }

      // 后序遍历
      BinarySearchTree.prototype.postOrderTraversal = function(fun){
        // 让postOrderTraversalNode去实现递归操作
        this.postOrderTraversalNode(this.root, fun)
      }

      // 内部使用
      BinarySearchTree.prototype.postOrderTraversalNode = function(node, fun){

        if (node) {

          // 1、遍历所有的左子树;
          this.postOrderTraversalNode(node.lchild, fun);

          // 2、遍历所有的右子树。
          this.postOrderTraversalNode(node.rchild, fun);

          // 3、打印当前结点
          fun(node.key);
        }
      }

      // 最大值
      BinarySearchTree.prototype.max = function(){
        var node = this.root;

        var key = null;
        while(node){
          key = node.key;
          node = node.rchild;
        }
        return key;
      }

      // 最小值
      BinarySearchTree.prototype.min = function(){
        var node = this.root;

        var key = null;
        while(node){
          key = node.key;
          node = node.lchild;
        }
        return key;
      }

      // 查找某个key
      BinarySearchTree.prototype.searchKey = function(key){
        var node = this.root;

        while(node != null){
          if (node.key < key) {
            node = node.rchild;
          }else if (node.key > key) { 
            node = node.lchild;
          }else{
            return true;
          }
        }
        return false;
      }

      // 删除某个结点
      BinarySearchTree.prototype.remove = function(key){
        // 1、寻找要删除的结点
        // 1.1 定义变量,保存信息
        var current = this.root; // 保存根结点
        var parent = null;   // 记录删除结点的父节点
        var isLeftChild = true;   //判断删除的结点是否是该父结点的左子结点

        // 1.2 查找要删除的结点
        while(current.key != key){
          parent = current;
          if (key < current.key) {
            isLeftChild = true;
            current = current.lchild;
          }else{
            isLeftChild = false;
            current = current.rchild;
          }

          // 已经找到最后一个结点还没有找到就退出
          if (current == null) return false;
        }

        // 2、根据对应的情况删除结点
        // 2.1删除的结点是叶子结点(即没有子结点)
        if (current.lchild == null && current.rchild == null) {
          if (current == this.root) {
            this.root = null;
          } else if (isLeftChild) {
            parent.lchild = null;
          } else {
            parent.rchild = null;
          }
        }

        // 2.2删除的结点有一个子结点
        else if (current.rchild == null) {
          if (current == this.root) {
            this.root = current.lchild;
          } else if (isLeftChild) {
            parent.lchild = current.lchild;
          } else {
            parent.rchild = current.lchild;
          }
        } else if (current.lchild == null) {
          if (current == this.root) {
            this.root = current.rchild;
          } else if (isLeftChild) {
            parent.lchild = current.rchild;
          } else {
            parent.rchild = current.rchild;
          }
        }

        // 2.3删除的结点两个子结点
        else {
          // 1、寻找后继
          var replaceNode = this.getReplaceNode(current);

          // 2、判断是否是根结点
          if (current == this.root) {
            this.root = replaceNode;
          } else if (isLeftChild) {
            parent.lchild = replaceNode;
          } else {
            parent.rchild = replaceNode;
          }

          // 3、将替代的结点的左子树  = 删除结点的左子树
          replaceNode.lchild = current.lchild;
        }
      }

      // 找后继的方法
      BinarySearchTree.prototype.getReplaceNode = function (delNode) {

        // 1、定义变量,来保存找到的后继
        var replaceNode = delNode; // 替代的结点
        var previous = delNode.rchild;  //删除结点的右结点
        var replaceParent = delNode;

        // 2、循环查找
        while(previous != null){
          replaceParent = replaceNode;
          replaceNode = previous;
          previous = previous.lchild;
        }

        // 3、判断找到的替换结点(后继)是否就是delNode的rchild结点,如果是则填补结点
        if (replaceNode != delNode.rchild) {
          // 后继结点必定是小于两个子结点的结点,将后继结点的父结点的左结点指向替代结点的右结点,连接操作。
          replaceParent.lchild = replaceNode.rchild;
          // 替换
          replaceNode.rchild = delNode.rchild;
        }
        return replaceNode;
      }
    }

    // 测试
    // 1、创建BinarySearchTree
    var bst = new BinarySearchTree();

    // 2、插入数据
    bst.insert(18);
    bst.insert(4);
    bst.insert(2);
    bst.insert(7);
    bst.insert(30);
    bst.insert(24);
    bst.insert(20);

    // 3、先序遍历
    var result1 = '';
    bst.preOrderTraversal(function (key){
      result1 += key + ' ';
    })
    console.log('先序遍历:' + result1); //18 4 2 7 30 24 20 

    // 4、中序遍历
    var result2 = '';
    bst.midOrderTraversal(function (key){
      result2 += key + ' ';
    })
    console.log('中序遍历:' + result2); //2 4 7 18 20 24 30 


    // 5、后序遍历
    var result3 = '';
    bst.postOrderTraversal(function (key){
      result3 += key + ' ';
    })
    console.log('后序遍历:' + result3); //2 7 4 20 24 30 18 


    console.log('最大值是' + bst.max());
    console.log('最小值是' + bst.min());
    console.log('是否存在24?' + bst.searchKey(24)); //true
    console.log('是否存在30?' + bst.searchKey(30)); //true
    console.log('是否存在5?' + bst.searchKey(5)); //false
    console.log('是否存在8?' + bst.searchKey(8)); //false
    console.log('是否存在500?' + bst.searchKey(500)); //false


    // 6、删除操作
    // 删除根结点18
    bst.remove(18);

    // 先序遍历
    var result4 = '';
    bst.preOrderTraversal(function (key){
      result4 += key + ' ';
    })
    console.log('先序遍历为18 4 2 7 30 24 20 ,删除结点18后得到先序遍历结果:' + result4); 
    //先序遍历为18 4 2 7 30 24 20 ,删除结点18后得到先序遍历结果:20 4 2 7 30 24 

    // 插入数据
    bst.insert(26);
    bst.insert(21);
    bst.insert(25);
    bst.insert(27);

    // 先序遍历
    var result5 = '';
    bst.preOrderTraversal(function (key){
      result5 += key + ' ';
    })
    console.log('在先序为20 4 2 7 30 24 的二叉树搜索树中插入26、21、25、27,得到先序遍历结果:' + result5); 
    //在先序为20 4 2 7 30 24 的二叉树搜索树中插入26、27、28、29,得到先序遍历结果:20 4 2 7 30 24 21 26 25 27 

    // 删除结点24
    bst.remove(24);

    // 先序遍历
    var result6 = '';
    bst.preOrderTraversal(function (key){
      result6 += key + ' ';
    })
    console.log('先序遍历为20 4 2 7 30 24 21 26 25 27 ,删除结点24后得到先序遍历结果:' + result6); 
    //先序遍历为20 4 2 7 30 24 21 26 25 27 ,删除结点24后得到先序遍历结果:20 4 2 7 30 25 21 26 27 
  </script>

</body>
</html>

 

Supongo que te gusta

Origin blog.csdn.net/weixin_42339197/article/details/99845315
Recomendado
Clasificación