JavaScript数据结构-树

BST的实现
其中对于二叉树删除节点最为复杂。
需要考虑节点是叶节点,有一个孩子(叶节点),有两个叶节点三种情况。
但是利用搜索二叉树左孩子小于右孩子的特点。
进行删除。
并且BST的实现很好的体现了递归的思想。
可以借此学习。

function printNode(value) {
  console.log(value);
}

function BinarySearchTree() {

  //插入新键
  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)
      }
    }
  }

//中序遍历
  var inOrderTraverseNode = function (node, callback) {
    if (node !== null){
      inOrderTraverseNode(node.left, callback);
      callback(node.key);
      inOrderTraverseNode(node.right, callback);
    }
  }

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

//后序
  var postOrderTraverseNode = function (node, callback) {
    if (node !== null){
      postOrderTraverseNode(node.left, callback);
      postOrderTraverseNode(node.right, callback);
      callback(node.key);
    }
  }

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

//最大值
  var maxNode = function (node) {
    if(node){
      while (node && node.right !== null) {
        node = node.right;
      }
      return node.key;
    }
    return null;
  }

//搜索
  var searchNode = function (node, key) {
    if(node === null){
      return false;
    }
    if(key < node.key){
      searchNode(node.left, key);
    }else if(key > node.key){
      searchNode(node.right, key);
    }else{
      return true;
    }
  }

//移除一个结点
  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;
      }
      //当有两个结点时
      console.log('已经查询到这里了')
      var aux = findMinNode(node.right);
      console.log(aux.key)
      node.key = aux.key;
      console.log('这是现在的node值'+node.key)
      node.right = removeNode(node.right, aux.key);
      console.log('这是node.right值'+node.right)
      return node;
    }
  }

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

  var Node = function (key) {
    this.key = key;
    this.left = null;
    this.right = null;
  }
  var root = null;
  //向树中插入一个新键
  this.insert = function (key) {
    var newNode = new Node(key);
    if(root === null){
      root = newNode;
    }else{
      insertNode(root, newNode);
    }
  }
  //中序遍历
  this.inOrderTraverse = function (callback) {
    inOrderTraverseNode(root, callback);
  }
  //先序遍历
  this.preOrderTraverse = function (callback) {
    preOrderTraverseNode(root, callback);
  }
  //后序遍历
  this.postOrderTraverse = function (callback) {
    postOrderTraverseNode(root, callback);
  }
  //搜索最小值。二叉搜索树,最小值为左树或者根
  this.min = function () {
    return minNode(root);
  }
  //搜索最大值。二叉搜索树,最大值为右树或者根
  this.max = function () {
    return maxNode(root);
  }
  //搜索一个特定的值
  this.search = function (key) {
    return searchNode(root, key);
  }
  //移除一个结点
  this.remove = function (key) {
    root = removeNode(root, key);
  }
}

var tree = new BinarySearchTree();
tree.insert(7)
tree.insert(15)
tree.insert(5)
tree.insert(3)
tree.insert(9)
tree.insert(8)
tree.insert(10)
tree.insert(13)
tree.insert(12)
tree.insert(14)
tree.insert(20)
tree.insert(18)
tree.insert(25)
tree.inOrderTraverse(printNode)
console.log(tree.max())
console.log(tree.min())
tree.remove(15)
tree.inOrderTraverse(printNode)

AVL树
AVL自平衡树,每个节点左子树高度和右子树高度差值为0,1或者-1

function AVLTree() {
  var Node = function (key) {
    this.key = key;
    this.left = null;
    this.right = null;
  };

  var root = null;

  this.getRoot = function () {
    return root;
  };

  //插入新节点
  var insertNode = function (node, element) {
    if (node === null) {
      node = new Node(element);
    } else if (element < node.key) {
      node.left = insertNode(node.left, element)
      if (node.left !== null) {
        //确认是否需要平衡
        if ((heightNode(node.left) - heightNode(node.right)) > 1) {
          //旋转
          if (element < node.left.key) {
            node = rotationLL(node);
          } else {
            node = rotationLR(node);
          }
        }
      }
    } else if (element > node.key) {
      node.right = insertNode(node.right, element)
      if (node.right !== null) {
        //确认是否需要平衡
        if ((heightNode(node.right) - heightNode(node.left)) > 1) {
          //旋转
          if (element > node.right.key) {
            node = rotationRR(node);
          } else {
            node = rotationRL(node);
          }
        }
      }
    }
    return node;
  }

  //计算节点高度
  var heightNode = function (node) {
    if (node === null) {
      return -1;
    } else {
      return Math.max(heightNode(node.left), heightNode(node.right)) + 1;
    }
  }

  //右-右(RR):向左的单旋转
  var rotationRR = function(node) {
    var tmp = node.right;
    node.right = tmp.left;
    tmp.left = node;
    return tmp;
  };

  //左-左(LL):向右的单旋转
  var rotationLL = function(node) {
    var tmp = node.left;
    node.left = tmp.right;
    tmp.right = node;
    return tmp;
  };

  //左-右(LR):向右的双旋转
  var rotationLR = function (node) {
    node.left = rotationRR(node.left);
    return rotationLL(node);
  }

  // 右-左(RL):向左的双旋转
  var rotationRL = function (node) {
    node.left = rotationLL(node.right);
    return rotationRR(node);
  }

  this.insert = function(element) {
    root = insertNode(root, element);
  };

  var parentNode;
  var nodeToBeDeleted;

  var removeNode = function(node, element) {
    if (node === null) {
      return null;
    }
    parentNode = node;

    if (element < node.key) {
      node.left = removeNode(node.left, element);
    } else {
      nodeToBeDeleted = node;
      node.right = removeNode(node.right, element);
    }

    if (node === parentNode) { //remove node
      if (nodeToBeDeleted !== null && element === nodeToBeDeleted.key) {
        if (nodeToBeDeleted === parentNode) {
          node = node.left;
        } else {
          var tmp = nodeToBeDeleted.key;
          nodeToBeDeleted.key = parentNode.key;
          parentNode.key = tmp;
          node = node.right;
        }
      }
    } else { //do balancing

      if (node.left === undefined) node.left = null;
      if (node.right === undefined) node.right = null;

      if ((heightNode(node.left) - heightNode(node.right)) === 2) {
        if (element < node.left.key) {
          node = rotationLR(node);
        } else {
          node = rotationLL(node);
        }
      }

      if ((heightNode(node.right) - heightNode(node.left)) === 2) {
        if (element > node.right.key) {
          node = rotationRL(node);
        } else {
          node = rotationRR(node);
        }
      }
    }

    return node;
  };

  this.remove = function(element) {
    parentNode = null;
    nodeToBeDeleted = null;
    root = removeNode(root, element);
  };

}

有兴趣可以加入Nodejs交流群,和大佬们一起成长!!!

群号:348108867

《JavaScript数据结构-树》 图片.png

    原文作者:差很多先生CL
    原文地址: https://www.jianshu.com/p/5af858755946
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞