【JavaScript数据结构】二叉树

76 阅读1分钟

在计算机科学中,二叉树是一个由节点组成的树形数据结构,其中每个节点最多只有两个子节点,通常称为“左子节点”和“右子节点”。

以下是一个基本的二叉树及其常见操作的实现与详细注释:

二叉树节点的定义

class TreeNode {
  constructor(value) {
    this.value = value;       // 节点的值
    this.left = null;        // 左子节点
    this.right = null;       // 右子节点
  }
}

二叉树的定义与操作

class BinaryTree {
  constructor() {
    this.root = null; // 根节点
  }

  // 插入操作: 对于这个简单的二叉树实现,我们只进行基本的插入
  // 注意:这不是二叉搜索树的插入操作
  insert(value) {
    const newNode = new TreeNode(value);
    if (!this.root) {
      this.root = newNode;
    } else {
      this._insertNode(this.root, newNode);
    }
  }

  _insertNode(node, newNode) {
    // 简单插入: 如果没有左子节点,插入左侧;否则插入右侧
    // 注意: 这种方法可能导致不平衡的树
    if (!node.left) {
      node.left = newNode;
    } else if (!node.right) {
      node.right = newNode;
    } else {
      // 如果左右子节点都存在,则递归到左子节点进行插入
      this._insertNode(node.left, newNode);
    }
  }

  // 前序遍历 (DFS: Depth-First Search)
  preOrder(callback) {
    this._preOrder(this.root, callback);
  }

  _preOrder(node, callback) {
    if (node) {
      callback(node.value);
      this._preOrder(node.left, callback);
      this._preOrder(node.right, callback);
    }
  }

  // 中序遍历 (DFS)
  inOrder(callback) {
    this._inOrder(this.root, callback);
  }

  _inOrder(node, callback) {
    if (node) {
      this._inOrder(node.left, callback);
      callback(node.value);
      this._inOrder(node.right, callback);
    }
  }

  // 后序遍历 (DFS)
  postOrder(callback) {
    this._postOrder(this.root, callback);
  }

  _postOrder(node, callback) {
    if (node) {
      this._postOrder(node.left, callback);
      this._postOrder(node.right, callback);
      callback(node.value);
    }
  }

  // 广度优先搜索 (BFS)
  levelOrder(callback) {
    if (!this.root) return;
    const queue = [this.root];

    while (queue.length) {
      const current = queue.shift();
      callback(current.value);
      if (current.left) queue.push(current.left);
      if (current.right) queue.push(current.right);
    }
  }
}

使用示例

let tree = new BinaryTree();

tree.insert(1);
tree.insert(2);
tree.insert(3);
tree.insert(4);
tree.insert(5);

// 使用前序遍历
tree.preOrder(value => console.log(value)); // 输出: 1, 2, 4, 5, 3

// 使用中序遍历
tree.inOrder(value => console.log(value)); // 输出: 4, 2, 5, 1, 3

// 使用后序遍历
tree.postOrder(value => console.log(value)); // 输出: 4, 5, 2, 3, 1

// 使用广度优先搜索
tree.levelOrder(value => console.log(value)); // 输出: 1, 2, 3, 4, 5