数据结构与算法-二叉搜索树

87 阅读1分钟
function BST() {
  function Node(key) {
    this.key = key;
    this.left = null;
    this.right = null;
  }
  this.root = null;

  // 插入方法 外部供用户插入
  BST.prototype.insert = function (key) {
    // 根据key创建节点
    let newNode = new Node(key);
    if (!this.root) {
      this.root = newNode;
    } else {
      this._insert(this.root, newNode);
    }
  };
  // 内部插入到树中
  BST.prototype._insert = function (root, node) {
    // 像左查找
    if (node.key < root.key) {
      if (!root.left) {
        root.left = node;
      } else {
        this._insert(root.left, node);
      }
    } else {
      if (!root.right) {
        root.right = node;
      } else {
        this._insert(root.right, node);
      }
    }
  };

  // 先序遍历
  BST.prototype.preSeaerch = function (handler) {
    if (!this.root) {
      return;
    }
    this._preSearch(this.root, handler);
  };
  // 内部对节点先序遍历(根左右)
  BST.prototype._preSearch = function (root, handler) {
    if (!root) {
      return;
    }
    // 处理经过的节点
    handler(root.key);
    this._preSearch(root.left, handler);
    this._preSearch(root.right, handler);
  };

  // 中序遍历
  BST.prototype.midSeaerch = function (handler) {
    if (!this.root) {
      return;
    }
    this._midSearch(this.root, handler);
  };
  // 内部对节点中序遍历(左根右)
  BST.prototype._midSearch = function (root, handler) {
    if (!root) {
      return;
    }
    // 处理经过的节点
    this._midSearch(root.left, handler);
    handler(root.key);
    this._midSearch(root.right, handler);
  };

  // 中序遍历
  BST.prototype.postSeaerch = function (handler) {
    if (!this.root) {
      return;
    }
    this._postSearch(this.root, handler);
  };
  // 内部对节点中序遍历(左右根)
  BST.prototype._postSearch = function (root, handler) {
    if (!root) {
      return;
    }
    // 处理经过的节点
    this._postSearch(root.left, handler);
    this._postSearch(root.right, handler);
    handler(root.key);
  };

  // 寻找最大值
  BST.prototype.max = function () {
    // 获取根节点
    let root = this.root;
    // 依次向右不断寻找
    let key = null;
    while (root) {
      key = root.key;
      root = root.right;
    }
    return key;
  };

  // 寻找最小值
  BST.prototype.min = function () {
    // 获取根节点
    let root = this.root
    // 依次向左不断寻找
    let key = null
    while (root) {
      key = root.key
      root = root.left
    }
    return key
  }

  // 搜索特定的值 (循环)
  BST.prototype.search = function (key) {
    // 获取根节点
    let root = this.root
    while (root) {
      if (key < root.key) {
        root = root.left
      } else if (key > root.key) {
        root = root.right
      } else {
        return true
      }
      return false
    }
  }

  // 删除节点
  BST.prototype.remove = function (key) {
    let root = this.root
    let parent = null
    let isLeft = true
    // 寻找要删除的节点
    while(root.key !== key) {
      parent = root
      if (key < root.key) {
        isLeft = true
        root = root.left
      } else {
        isLeft = false
        root = root.right
      }
      // 已经找到了最后的节点,依然没有找到
      if (!root) {
        return false
      }
    }
    // 1.删除的节点没有子节点
    if (!root.left && !root.right) {
      if (root === this.root) {
        this.root = null
      } else if(isLeft) {
        parent.left = null
      } else {
        parent.right = null
      }
    }
    // 2.删除的节点有一个子节点
    else if(!root.right) {
      if (root === this.root) {
        this.root = root.left
      } else if(isLeft) {
        parent.left = root.left
      } else {
        parent.right = root.left
      }
    } else if(!root.left) {
      if (root === this.root) {
        this.root = root.right
      } else if (isLeft) {
        parent.left = root.right
      } else {
        parent.right = root.right
      }
    }
    // 2.删除的节点有两个个子节点
    else {
      // 获取后续节点
      let childNode = this.getChildNode(root)
      if (root === this.root) {
        this.root = childNode
      } else if (isLeft) {
        parent.left = childNode
      } else {
        parent.right = childNode
      }
      // 将删除的节点的左节点等于root.left
      childNode.left = root.left
    }
  }
  // 寻找后续节点
  BST.prototype.getChildNode = function (delNode) {
    let childNode = delNode
    let current = delNode.right
    let childNodeParent = delNode
    while (current) {
      childNodeParent = childNode
      childNode = current
      current = current.left
    }
    // 判断寻找的节点是否就是delNode的右节点
    if (childNode !== delNode.right) {
      childNodeParent.left = childNode.right
      childNode.right = delNode.right
    }
    return childNode
  }
}
let tree = new BST();
tree.insert(11);
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.insert(6);
let preStr = "";
tree.preSeaerch((key) => {
  preStr += key + " ";
});
let midStr = "";
tree.midSeaerch((key) => {
  midStr += key + " ";
});
let postStr = "";
tree.postSeaerch((key) => {
  postStr += key + " ";
});
console.log(preStr);
console.log(midStr);
console.log(postStr);
console.log(tree.max());
console.log(tree.min());
console.log(tree.search(11));
console.log(tree);
tree.remove(5)
let preStr2 = "";
tree.preSeaerch((key) => {
  preStr2 += key + " ";
});
console.log(preStr2);