Data Structure and Algorithmic Solution of Binary Search Tree (js Edition)

Posted by mark_nsx on Thu, 03 Oct 2019 04:39:27 +0200

Written in front

This paper introduces the data structure of binary search tree and the front-end implementation of some operations, and some corresponding LeetCode problems.

Node class

class Node {
    constructor({value, left, right}) {
        this.value = value;
        this.left = left;
        this.right = right;
    }
}

Binary Search Tree Class

class BST {
    constructor(value) {
        this.root = value ? new Node({value}) : null
    }
}

Insertion of Basic Operations

// Give a value to insert the tree as a node. Recursive implementation
    insert(value) {
        // If there is no root node, the insertion value is the root node.
        if (!this.root) {
            this.root = new Node({value})
        }

        let curNode = this.root
        let fn = (curNode) => {
            // The insertion value may be larger or smaller than the current node value
            if (value < curNode.value) {
                // If there is no left node, you can insert the value to be inserted into the left node of the current node
                if (!curNode.left) {
                    curNode.left = new Node({value})
                    return true;
                } else {
                    curNode = curNode.left
                    return fn(curNode)
                }
            } else if (value > curNode.value) {
                if (!curNode.right) {
                    curNode.right = new Node({value})
                    return true;
                } else {
                    curNode = curNode.right
                    return fn(curNode)
                }
            } else {
                // Binary search trees do not allow duplicate values.
                return false;
            }
        }
        return fn(curNode)
    }

Finding Basic Operations

// Find if a value exists and return bool.
   search(value) {
        if (!this.root) return false;
        if (this.root.value === value) {
            return true;
        }
        let curNode = this.root;
        let fn = (curNode) => {
            if (value === curNode.value) return true;
            if (value < curNode.value) {
                // Search to the end, no search, return false
                if (!curNode.left) {
                    return false;
                } else {
                    curNode = curNode.left
                    return fn(curNode)
                }
            } else if (value > curNode.value) {
                if (!curNode.right) {
                    return false;
                } else {
                    curNode = curNode.right
                    return fn(curNode)
                }
            }
        }
        return fn(curNode)
    }

Priority traversal of basic operations

// Preorder traversal
    preTraversal(root){
        if (!root) return [];
        let arr = []
        let curNode = this.root;
        let fn = (curNode) => {
            // Recursive method, first place the root node, then traverse the left subtree, and then traverse the right subtree.
            arr.push(curNode.value)
            if (curNode.left){
                fn(curNode.left)
            }
            if (curNode.right){
                fn(curNode.right)
            }
        }
        fn(curNode)
        return arr;
    }

LeetCode's Solution to Corresponding Topics

With this data structure and basic operation, some LeetCode algorithmic problems can be brushed through.
Here are some related questions and solutions.

Search in LeetCode700-easy-binary search tree


/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} val
 * @return {TreeNode}
 */
var searchBST = function(root, val) {
    if (!root) return null;
    if (root.val === val) {
        return root;
    }
    let curNode = root;
    let fn = (curNode) => {
        if (val === curNode.val) return curNode;
        if (val < curNode.val) {
            if (!curNode.left) {
                return null;
            } else {
                curNode = curNode.left
                return fn(curNode)
            }
        } else if (val > curNode.val) {
            if (!curNode.right) {
                return null;
            } else {
                curNode = curNode.right
                return fn(curNode)
            }
        }
    }
    return fn(curNode)
};

Insertion in 701-medium-binary search tree

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} val
 * @return {TreeNode}
 */
var insertIntoBST = function(root, val) {
    if (!root) {
        root = new TreeNode(val)
        return root;
    }

    let curNode = root
    let fn = (curNode) => {
        if (val < curNode.val) {
            if (!curNode.left) {
                curNode.left = new TreeNode(val)
                return root;
            } else {
                curNode = curNode.left
                return fn(curNode)
            }
        } else if (val > curNode.val) {
            if (!curNode.right) {
                curNode.right = new TreeNode(val)
                return root;
            } else {
                curNode = curNode.right
                return fn(curNode)
            }
        }
    }
    return fn(curNode)
};

Priority traversal of 589-easy-N fork tree


/**
 * // Definition for a Node.
 * function Node(val,children) {
 *    this.val = val;
 *    this.children = children;
 * };
 */
/**
 * @param {Node} root
 * @return {number[]}
 */
var preorder = function(root) {
    if (!root) return []
    let arr = []
    let curNode = root
    let fn = (curNode) => {
        arr.push(curNode.val);
        if (curNode.children.length){
            for(let i = 0; i < curNode.children.length; i++){
                fn(curNode.children[i])
            }
        }
    }
    fn(curNode)
    return arr
};

The Range and Sum of 938-easy-binary Search Tree

This problem is to traverse in order to get node data, organize into an array, and then find.


/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} L
 * @param {number} R
 * @return {number}
 */
var rangeSumBST = function(root, L, R) {
    if (!root) return 0;
    let arr = []
    let curNode = root;
    let fn = (curNode) => {
        arr.push(curNode.val)
        if (curNode.left){
            fn(curNode.left)
        }
        if (curNode.right){
            fn(curNode.right)
        }
    }
    fn(curNode)

    let sum = 0
    for(let i = 0; i < arr.length; i++){
        if(arr[i] <= R && arr[i] >= L){
            sum += arr[i]
        }
    }
    return sum;
};

summary

Subsequently, the remaining basic operations and topics will be updated.
You can also directly focus on the author's front-end algorithm library: https://github.com/cunzaizhuy...
Here are nearly two hundred LeetCode algorithm solutions, which are constantly updated.

Topics: Javascript github