JavaScript implements the operation of binary search tree (insert, traverse and maximum value) (ES6)

Binary tree

Tree: it is a nonlinear table structure with n (n > = 0) nodes. When n=0, it is called an empty tree. In any non empty tree:

  • There is only one root node
  • When n > 1, the other nodes can be divided into m (M > 0) disjoint finite sets T1,T2,..., Tm. Each set itself is a tree, which is called the subtree of the root

Binary tree: a tree in which each node has at most two child nodes. These two nodes are the left child node and the right child node respectively

Full binary tree: there is a binary tree with all leaves at the bottom. Except for leaf nodes, each node has left and right child nodes

Complete binary tree: there is a binary tree. The leaf nodes are in the bottom two layers. The leaf nodes of the last layer are continuous from left to right, and there is no missing in the middle. Besides the last layer, the number of nodes in other layers should reach the maximum

Properties of binary tree:

  • Property 1: the maximum number of nodes on layer i of binary tree is 2{i-1} (i ≥ 1).
  • Property 2: a binary tree with depth K has at most 2{k}-1 nodes (K ≥ 1).
  • Property 3: the height of a binary tree containing N nodes is at least log2 (n+1).
  • Property 4: in any binary tree, if the number of terminal nodes is n0 and the number of nodes with degree 2 is n2, then n0=n2+1.

Traversal of binary tree: no repeated access to each node in the binary tree (recursive idea)

  • Preorder traversal: root left right
  • Middle order traversal: left root right
  • Post order traversal: left right root
  • Breadth first traversal (hierarchical traversal): access layer by layer. After the node access of each layer is completed, access the next layer. No tree can be drawn through hierarchical traversal

Binary search tree: it is a kind of binary tree, but it only allows the left node to store smaller values (than the parent node) and the right node to store larger (or equal) values (than the parent node)

ES6 implements binary search tree:

class Node {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

class binarySearchTree {
    constructor() {
        this.root = null;
        this.result_array=[];
    }

    //Create a binary search tree, that is, the value of the root node is greater than that of the left node and less than that of the right node
    insertNodeByFather(node, newNode) {
        //If newnode < node value
        if (newNode.val < node.val) {
            //Judge whether the left node is empty
            if (node.left === null) {
                node.left = newNode;
            } else { //Continue to recursively find the next layer
                this.insertNodeByFather(node.left, newNode);
            }
        } else { //If newnode > node value
            if (node.right === null) {
                node.right = newNode;
            } else {
                this.insertNodeByFather(node.right, newNode);
            }
        }
    }
    insert(val) {
        //Create a new node
        let node = new Node(val);
        if (this.root === null) { //If there is no root node
            this.root = node;
        } else { //Otherwise, the insertNode method is called
            this.insertNodeByFather(this.root, node);
        }
    }
    //Preorder traversal: root right left
    preOrder(node) {
            if (node) {
                this.result_array.push(node.val);
                this.preOrder(node.left);
                this.preOrder(node.right);
            }
    }

    //Middle order traversal: left root right
    inOrder(node) {
            if (node) {
                this.inOrder(node.left);
                this.result_array.push(node.val);
                this.inOrder(node.right);
            }
    }

    //Postorder traversal: left and right roots
    postOrder(node) {
        if (node) {
            this.postOrder(node.left);
            this.postOrder(node.right);
            this.result_array.push(node.val);
        }
    }
    //Breadth first traversal (hierarchical traversal) starts from the first layer (root node) of the binary tree and traverses layer by layer from top to bottom; In the same layer, the nodes are accessed one by one from left to right
    levelOrderTraversal(node) {
        if (!node) {
            throw new Error('Empty Tree');
        }
        let que = [];
        que.push(node)
        while (que.length !== 0) {
            node = que.shift()
            this.result_array.push(node.val)
            if (node.left) que.push(node.left)
            if (node.right) que.push(node.right)
        }
    }
    //Clear the value of the stored tree node
    init(){
        this.result_array=[];
    }

    //Search minimum
    minNode(node){
        if (!node) return null;
        while (node.left){
            node=node.left;
        }
        return node.val;
    }

    //Search maximum
    maxNode(node){
        if (!node) return null;
        while (node.right){
            node=node.right;
        }
        return node.val;
    }
}

Test code:

let tree = new binarySearchTree();
let arr = [11,7,15,5,9,4,6,8,10];
arr.forEach((a) => {
    tree.insert(a);
});

let pre_arr = []; //Store preorder traversal sequence
let in_arr = []; //Storing middle order traversal sequence
let post_arr = []; //Store post order traversal sequence
let level_arr = []; //Store hierarchical traversal sequence

tree.preOrder(tree.root);
pre_arr=tree.result_array;
console.log('Preorder traversal:',pre_arr);

tree.init();//Clear the values in the array
tree.inOrder(tree.root);
in_arr=tree.result_array;
console.log('Middle order traversal:',in_arr);

tree.init();
tree.postOrder(tree.root);
post_arr=tree.result_array;
console.log('Post order traversal:',post_arr);

tree.init();
tree.levelOrderTraversal(tree.root);
level_arr=tree.result_array;
console.log('Hierarchy traversal:',level_arr);

console.log('Minimum:',tree.minNode(tree.root));
console.log('Maximum:',tree.maxNode(tree.root));

Output results:

Case: input the array results of the preorder and inorder traversal of the binary tree to determine the binary tree structure

 class binaryTree {
    constructor(v, l, r) {
        this.val = v;
        this.left = l;
        this.right = r
    }
}

/**
 * Enter the results of preorder traversal and inorder traversal of a binary tree, please rebuild the binary tree.
 * It is assumed that the input pre order traversal and middle order traversal results do not contain duplicate numbers.
 * For example, enter the preorder traversal sequence {1,2,4,7,3,5,6,8} and the middle order traversal column {4,7,2,1,5,3,8,6},
 * Rebuild the binary tree and return.
 * 
 *   Input: previous order: [1,2,3,4,5,6,7], middle order: [3,2,4,1,6,5,7]   
     Output: tree structure
 */

function reConstructBinaryTree(pre, next) {
    // Recursive exit
    if (pre.length == 0 || next.length == 0 || pre.length != next.length) {
        return null;
    }
    // Get the root node
    let root = new binaryTree(pre[0]);
    // The position of the root node found in the middle order traversal
    let i = 0;
    while (next[i] != root.val) {
        i++;
    }
    //Determine the pre order traversal length of the left subtree
    let preLeft = new Array(i);
    //Determine the length of order traversal in the left subtree
    let inLeft = new Array(i);

    //Determine the preorder traversal length of the right subtree
    let preRight = new Array(next.length - i - 1);
    //Determine the order traversal length in the right subtree
    let inRight = new Array(next.length - i - 1);

    // Traversal gets the value of the middle order traversal before the left and right subtrees in turn
    for (let j = 0; j < next.length; j++) {
        if (j < i) {
            preLeft[j] = pre[j + 1];  //Start with j+1
            inLeft[j] = next[j];      //Start with j
        } else if (j > i) {
            preRight[j - i - 1] = pre[j];
            inRight[j - i - 1] = next[j];
        }
    }
    // recursion
    root.left = reConstructBinaryTree(preLeft, inLeft);
    root.right = reConstructBinaryTree(preRight, inRight);
    return root;
}

Test: determine the structure of the tree with known preorder and inorder

let pre = [1, 2, 3, 4, 5, 6, 7];
let next = [3, 2, 4, 1, 6, 5, 7];
let root = reConstructBinaryTree(pre, next);
console.log(root);

Structure of binary tree:

Keywords: Javascript Algorithm data structure Binary tree

Added by babyrocky1 on Fri, 03 Sep 2021 04:17:05 +0300