数据结构与算法之树(Tree)

139 阅读1分钟

1. 概念

是一种非线性的数据结构,以分层方式存储数据,用来表示有层级关系的数据

2. 特点

每棵树至多只有一个根结点根结点会有很多子节点,每个子节点只有一个父结点

父结点子节点是相对的。

**3. 1. 生活中的例子: **

家谱、公司组织架构图。

二叉搜索树的实现

// 节点
class Node {
  constructor(key) {
    this.key = key;
    this.left = null; // 左节点
    this.right = null; // 右节点
  }
}

// 二叉搜索树
class BinarySearchTree {
  constructor() {
    this.root = null;
  }
  /**
   * 插入一个节点
   * @param {*} node 插入的位置节点
   * @param {*} newNode 插入的节点
   */
  insertNode(node, newNode) {
    if (newNode.key < node.key) {
      if (node.left === null && node.right === null) {
        node.left = newNode;
      } else if (node.left !== null && node.right === null) {
        node.right = newNode;
      } else {
        this.insertNode(node.left, newNode);
      }
    } else {
      if (node.left === null && node.right === null) {
        node.left = newNode;
      } else if (node.left !== null && node.right === null) {
        node.right = newNode;
      } else {
        this.insertNode(node.right, newNode);
      }
    }
  }

  /**
   * 插入操作
   * @param {*} key
   */
  insert(key) {
    let newNode = new Node(key);
    if (this.root === null) {
      this.root = newNode;
    } else {
      this.insertNode(this.root, newNode);
    }
  }
  searchNode(node, key) {
    if (node === null) return false;
    if (key < node.key) {
      return this.searchNode(node.left, key);
    } else if (key > node.key) {
      return this.searchNode(node.right, key);
    }
    return true;
  }

  /**
   * 搜索操作
   * @param {*} key
   */
  search(key) {
    return this.searchNode(this.root, key);
  }

  /**
   * 最小值的节点
   */
  min() {
    let node = this.root;
    if (node === null) return null;
    while (node && node.left !== null) {
      node = node.left;
    }
    return node.key;
  }

  /**
   * 最大值的节点
   */
  max() {
    let node = this.root;
    if (node === null) return null;
    while (node && node.right !== null) {
      node = node.right;
    }
    return node.key;
  }

  /**
   * 找到最小节点
   * @param {*} node
   */
  findMinNode(node) {
    if (node === null) return null;
    while (node && node.left !== null) {
      node = node.left;
    }
    return node;
  }

  /**
   * 删除一个节点
   * @param {*} node
   * @param {*} key
   */
  removeNode(node, key) {
    if (node === null) return null;
    if (key < node.key) {
      node.left = this.removeNode(node.left, key);
      return node;
    } else if (key > node.key) {
      node.right = this.removeNode(node.right, key);
      return node;
    } else {
      // 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;
      }
      // 3.有两个子节点
      let curNode = this.findMinNode(node.right);
      node.key = curNode.key;
      node.right = this.removeNode(node.right, curNode.key);
      return node;
    }
  }

  /**
   * 删除一个节点
   * @param {*} key
   */
  remove(key) {
    if (this.root === null) return null;
    this.root = this.removeNode(this.root, key);
  }
}