javascript数据结构与算法之二叉树

155 阅读1分钟

二叉树封装

/**
 * @class BinTreeNode 二叉树结点类
 */
class BinTreeNode {
  constructor(data) {
    this.leftNode = null;
    this.rightNode = null;
    this.parentNode = null;
    this.data = data;
  }
}

/**
 * @class BinaryTree 二叉树类
 */
class BinaryTree {
  constructor() {
    this.root = null;
  }
  /**
   *
   * @method 初始化二叉树
   * @param {string} initString 广义表字符串
   * @memberof BinaryTree
   */
  init(initString) {
    const initStack = new Stack();
    let currentNode;
    let flag = 0;
    for (let i = 0; i < initString.length; i++) {
      const item = initString[i];
      if (item == "(") {
        initStack.push(currentNode);
        flag = 1;
      } else if (item == ")") {
        initStack.pop();
      } else if (item == ",") {
        flag = 2;
      } else {
        currentNode = new BinTreeNode(item);
        if (flag == 0) {
          this.root = currentNode;
        } else if (flag == 1) {
          const top = initStack.top();
          top.leftNode = currentNode;
          currentNode.parentNode = top;
        } else if (flag == 2) {
          const top = initStack.top();
          top.rightNode = currentNode;
          currentNode.parentNode = top;
        }
      }
    }
  }
  // /**
  //  * @method 递归实现前序遍历
  //  * @param {object} node 二叉树根节点
  //  * @return {*} 
  //  * @memberof BinaryTree
  //  */
  // preOrder(node) {
  //   if (!node) return null;
  //   console.log(node.data);
  //   this.preOrder(node.leftNode);
  //   this.preOrder(node.rightNode);
  // } 
  /**
   * @method 非递归实现前序遍历
   * @param {object} node 二叉树根节点
   * @return {*} 
   * @memberof BinaryTree
   */
  preOrder(node) {
    if (!node) return null;
    const stack = new Stack();
    while (node) {
      console.log(node.data);
      node.rightNode && stack.push(node.rightNode);
      if (node.leftNode) {
        node = node.leftNode;
      } else {
        node = stack.pop();
      }
    }
  }
  // /**
  //  * @method 递归实现中序遍历
  //  * @param {object} node 二叉树根节点
  //  * @return {*} 
  //  * @memberof BinaryTree
  //  */
  // inOrder(node) {
  //   if (!node) return null;
  //   this.inOrder(node.leftNode);
  //   console.log(node.data);
  //   this.inOrder(node.rightNode);
  // }
  /**
   * @method 非递归实现中序遍历
   * @param {object} node 二叉树根节点
   * @return {*} 
   * @memberof BinaryTree
   */
  inOrder(node) {
    if (!node) return null;
    let currentNode = node;
    const stack = new Stack();
    while (true) {
      while (currentNode) {
        stack.push(currentNode);
        currentNode = currentNode.leftNode;
      }
      const popItem = stack.pop();
      console.log(popItem.data);
      currentNode = popItem.rightNode;
      if (!currentNode && stack.isEmpty()) break;
    }
  }
  // /**
  //  * @method 递归实现后序遍历
  //  * @param {object} node 二叉树根节点
  //  * @return {*} 
  //  * @memberof BinaryTree
  //  */
  // postOrder(node) {
  //   if (!node) return null;
  //   this.postOrder(node.leftNode);
  //   this.postOrder(node.rightNode);
  //   console.log(node.data);
  // }
  /**
   * @method 非递归实现后续遍历
   * @param {*} node 二叉树根节点
   * @return {*} 
   * @memberof BinaryTree
   */
  postOrder(node) {
    if (!node) return null;
    let currentNode = node;
    const stack = new Stack();
    while (true) {
      while (currentNode) {
        stack.push({ node: currentNode, flag: 0 });
        currentNode = currentNode.leftNode;
      }
      let popItem = stack.pop();
      if (popItem.node.rightNode && popItem.flag == 0) {
        popItem.flag = 1;
        stack.push(popItem);
        currentNode = popItem.node.rightNode;
      } else {
        console.log(popItem.node.data);
      }
      if (stack.isEmpty()) break;
    }
  }
  /**
   * @methods 获取二叉树节点数
   * @param {*} node 二叉树根节点
   * @return {*} 
   * @memberof BinaryTree
   */
  getTreesize(node) {
    if (!node) return 0;
    let leftSize = this.getTreesize(node.leftNode);
    let rightSize = this.getTreesize(node.rightNode);
    return leftSize + rightSize + 1;
  }
  /**
   *
   * @method 获取二叉树高度
   * @param {object} node 二叉树根节点
   * @return {*} 
   * @memberof BinaryTree
   */
  getTreeHeight(node) {
    if (!node) return 0;
    let leftHeight = this.getTreeHeight(node.leftNode);
    let rightHeight = this.getTreeHeight(node.rightNode);
    if (leftHeight > rightNode) {
      return leftHeight + 1;
    } else {
      return rightHeight + 1;
    }
  }
  /**
   * 查找二叉树上的节点
   * @param {object} node 目标树根节点
   * @param {*} data 要查找的节点数据
   * @return {*} 
   * @memberof BinaryTree
   */
  findNode(node, data) {
    if (!node) return null;
    if (node.data === data) return node;
    const leftResult = this.findNode(node.leftNode, data);
    if (leftResult) return leftResult;
    return this.findNode(node.rightNode, data);
  }
  /**
   *
   * @method 获取所有父节点
   * @param {object} node 当前节点
   * @return {array} 父节点数组
   * @memberof BinaryTree
   */
  getParentNodes(node) {
    if (!node) return null;
    let parentNodeList = [];
    while(node.parentNode) {
      parentNodeList.push(node.parentNode);
      node = node.parentNode;
    }
    return parentNodeList;
  }
}

const binaryTree = new BinaryTree();
binaryTree.init("A(B(D,E(G,)),C(,F))");
binaryTree.postOrder(binaryTree.root);

求二叉树的镜像

/**
 * @function 求二叉树的镜像
 * @param {object} node 目标二叉树根节点
 * @return {*} 
 */
function getMirrorTree(node) {
  if (!node) return null;
  const tempNode = node.rightNode;
  node.rightNode = node.leftNode;
  node.leftNode = tempNode;
  getMirrorTree(node.leftNode);
  getMirrorTree(node.rightNode);
}

求两个节点的最近父节点

/**
 *
 * @function 寻找两节点的最近祖先节点
 * @param {*} nodeRoot 根节点
 * @param {*} nodeOne 节点一
 * @param {*} nodeTwo 节点二
 */
function getNearestParentNode(nodeRoot, nodeOne, nodeTwo) {
  if (!nodeRoot || nodeRoot == nodeOne || nodeRoot == nodeTwo) return nodeRoot;
  const left = getNearestParentNode(nodeRoot.leftNode, nodeOne, nodeTwo);
  const right = getNearestParentNode(nodeRoot.rightNode, nodeOne, nodeTwo);
  if (left && right) return nodeRoot;
  if (left) return left;
  return right;
}

分层打印二叉树

function printLevelNode(rootNode) {
  if (!rootNode) console.log(null);
  const list = [rootNode, 0];
  let printStr = "";
  while (list.length) {
    const shiftItem = list.shift();
    if (shiftItem == 0) {
      console.log(printStr);
      if (list.length) {
        list.push(0);
        printStr = "";
      } else {
        break;
      }
      continue;
    }
    printStr += `${shiftItem.data} `;
    if (shiftItem.leftNode) list.push(shiftItem.leftNode);
    if (shiftItem.rightNode) list.push(shiftItem.rightNode);
  }
}

获取指定层的节点数

function getlevelNodeCounts(node, level) {
  if (!node || !level) return 0;
  let list = [node, 0];
  let index = 1;
  let counts = 0;
  while (list.length) {
    const shiftItem = list.shift();
    if (shiftItem == 0) {
      if (index == level) {
        break;
      } else {
        counts = 0;
        list.push(0);
        index++;
        continue;
      }
    }
    if (shiftItem.leftNode) list.push(shiftItem.leftNode);
    if (shiftItem.rightNode) list.push(shiftItem.rightNode);
    counts++;
  }
  return counts;
}