头图

cause

Binary tree is almost a knowledge point that must be asked in the interview process. Most of the description process is implemented in C, C++, JAVA, python and other languages. Here, js language is used to implement the next similar functions, front-end, nodejs direction and full stack direction. Students can use it as a reference.

Example

All the following implementations are based on the following binary tree example:

As shown in the figure, the establishment process uses the binarytree library, the code is as follows:

const BinaryTree = require('binarytree');

let binaryTree = new BinaryTree('F');
let bNode = binaryTree.insert('B', 'left', binaryTree.root);
let aNode = binaryTree.insert('A', 'left', bNode);
let dNode = binaryTree.insert('D', 'right', bNode);
let cNode = binaryTree.insert('C', 'left', dNode);
let eNode = binaryTree.insert('E', 'right', dNode);
let gNode = binaryTree.insert('G', 'right', binaryTree.root);
let iNode = binaryTree.insert('I', 'right', gNode);
let hNode = binaryTree.insert('H', 'left', iNode);

DFS

Deep traversal has three traversal methods: preorder, middle order and postorder. The recursive method is very easy to understand. The code is as follows:

Preorder traversal: root node ---> left subtree ---> right subtree

function preorderDFS(root) {
  const nodeList = [];
  preorder(root, nodeList)
  return nodeList;

  function preorder(root, nodeList) {
    if (root !== null) {
      nodeList.push(root.data)
      preorder(root.left, nodeList);
      preorder(root.right, nodeList);
    }
  }
}

Middle-order traversal: left subtree ---> root node ---> right subtree

function inorderDFS(root) {
  const nodeList = [];
  inorder(root, nodeList);
  return nodeList;

  function inorder(root, nodeList) {
    if (root !== null) {
      inorder(root.left, nodeList);
      nodeList.push(root.data);
      inorder(root.right, nodeList);
    }
  }
}

Post-order traversal: left subtree ---> right subtree ---> root node

function postorderDFS(root) {
  const nodeList = [];
  postorder(root, nodeList);
  return nodeList;

  function postorder(root, nodeList) {
    if (root !== null) {
      postorder(root.left, nodeList);
      postorder(root.right, nodeList);
      nodeList.push(root.data)
    }
  }
}

BFS

It is sufficient to traverse by level. A queue is needed, and the root node is added to the queue first. The queue performs the dequeue operation. If the dequeue element has the left child enters the team, it does not matter if there is no child, and the right child enters the team, if not, it does not matter. Then continue the above operation until the queue is empty.

function BFS(root) {
  const q = [root];
  const nodeList = [];
  while (q.length > 0) {
    const node = q.pop();
    nodeList.push(node.data);
    if (node.left !== null) q.unshift(node.left);
    if (node.right !== null) q.unshift(node.right);
  }
  
  return nodeList;
}

Snake print

The printing sequence is shown in the figure:

Similar to BFS, but different, you can use BFS thinking to think.
The children of the node printed first in the previous layer are printed after the next layer. According to this idea, the child nodes need to be stored in the stack.
For the two layers, the printing order of the left and right children is reversed, so we need two implementations, one for storing odd-numbered nodes in the stacking order of left children and then right children, and the other for storing even-numbered nodes in the order of entering the stack first. The right child follows the left child.
Suppose lrStack stores odd-numbered layer nodes, and rlStack stores even-numbered layer nodes:

  1. The root node F is the first layer, the odd-numbered layer, so lrStack enters F
  2. All elements of lrStack are out of the lamp, that is, F is out of the lamp. At the same time, because the next layer is an even-numbered layer, it enters the lamp in the order of the right child and the left child.
  3. rlStack all elements B ---> G, because the next layer is an odd layer, so enter the lrStack in the order of the left child and the right child
  4. lrStack all elements I ---> D ---> A, because the next layer is an even-numbered layer, so enter the rlStack in the order of right child and left child
  5. rlStack produces all elements C ---> E ---> H, because the next layer has no data, end

According to the idea, the code is as follows:

function printBintryTree(root) {
  const lrStack = [];
  const rlStack = [];
  lrStack.push(root);
  while(lrStack.length > 0 || rlStack.length > 0) {
    if (lrStack.length > 0 && rlStack.length === 0) {
      while (lrStack.length > 0) {
        const tNode = lrStack.pop();
        console.log(tNode.data);
        if (tNode.right !== null) {
          rlStack.push(tNode.right);
        }
        if (tNode.left !== null) {
          rlStack.push(tNode.left);
        }
      }
    }
    if (rlStack.length > 0 && lrStack.length === 0) {
      while (rlStack.length > 0) {
        const tNode = rlStack.pop();
        console.log(tNode.data);
        if (tNode.left !== null) {
          lrStack.push(tNode.left);
        }
        if (tNode.right !== null) {
          lrStack.push(tNode.right);
        }
      }
    }
  }
}

Sample call

// 蛇形打印
printBintryTree(binaryTree.root); // F B G I D A C E H
// 广度遍历
console.log(BFS(binaryTree.root)); // ['F', 'B', 'G', 'A', 'D', 'I', 'C', 'E', 'H']
// 深度遍历
console.log(preorderDFS(binaryTree.root)); // ['F', 'B', 'A', 'D', 'C', 'E', 'G', 'I', 'H']
console.log(inorderDFS(binaryTree.root)); // ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
console.log(postorderDFS(binaryTree.root)); // ['A', 'C', 'E', 'D', 'B', 'H', 'I', 'G', 'F'];

小磊
352 声望884 粉丝

以一颗更加开放,更加多元,更加包容的心走进别人的世界