Data structure 7-- binary search trees and balanced binary tree

Binary search tree

  1. Features binary search tree (BST, Binary Search Tree)
    all key non-empty left subtree is less than its root key
    key non-empty right subtree of all keys greater than its roots Hey but the
    left and right sub tree itself is a binary search tree
  2. Preorder traversal
    to access the root node, and then traverse left subtree, traverse the right subtree last
    Here Insert Picture Description
    recursive traversal, access the root node, the first print, and then traverse the left subtree and right subtree
  3. Postorder
    first traverse the left subtree, then traverse the right subtree, root last visit
    Here Insert Picture Description
  4. Preorder
    first traverse the left subtree, then visit the root node, and finally traversing the right subtree
    Here Insert Picture Description
  5. Delete Node
    three cases: the node is about to be deleted leaf node / node to be removed only the left subtree or only a right subtree / sub tree has to be removed

Precursor: left subtree node maximum
minimum right subtree of node: successor

//封装二叉搜索树
function BinarySearchTree(){

    this.root = null;
    //创建子树节点 拥有键值、左子树和右子树属性
    function NewNode(key){
        this.key = key;
        this.leftTree = null;
        this.rightTree = null;
    }
    this.resultString = " ";

    //插入子树
    BinarySearchTree.prototype.insert = function(key){
        let newNode = new NewNode(key);
        //如果BST为空,令要插入的子树为根节点
        if(this.root == null){
            this.root = newNode;
        }else{
            //如果BST不为空 调用insertNode
            this.insertNode(this.root,newNode)
        }
    }
    BinarySearchTree.prototype.insertNode = function(currentNode,newNode){
        //键值大小比较
        if(newNode.key < currentNode.key){ //新插入的键值比当前节点的键值小 去左子树找
            //判断当前子树是否有子树 如果没有 直接插入 有的话继续递归
            if(currentNode.leftTree == null){
                currentNode.leftTree  = newNode;
            }else{
                this.insertNode(currentNode.leftTree,newNode);
            }

        }else{
            // //新插入的子树的键值比当前子树的键值大,去右子树找
            if(currentNode.rightTree == null){
                currentNode.rightTree = newNode;
            }else{
                this.insertNode(currentNode.rightTree,newNode);
            }
        }
    }

    //查找树中的最大值和最小值
    //BST中最左边的叶子节点的键值最小 最右边的叶子节点的键值最大
    BinarySearchTree.prototype.minNode = function(){
        //如果是空树 返回false
        if(this.root == null) return false;
        let currentNode = this.root;//保存当前子树
        while(currentNode.leftTree){
            currentNode = currentNode.leftTree
        }
        return currentNode.key;
    }
    BinarySearchTree.prototype.maxNode = function(){
        //如果是空树 返回false
        if(this.root == null) return false;
        let currentNode = this.root;
        while(currentNode.rightTree){
            currentNode = currentNode.rightTree;
        }
        return currentNode.key;
    }

    //搜索指定的键值
    //找不到的两种情况:1.真的没有 2.空树
    BinarySearchTree.prototype.searchNode = function(key){
        //键值比较 向左还是向右寻找
        if(!this.root) return false;
        let currentNode = this.root;
        while(currentNode){
            if(key < currentNode.key){ //小
                currentNode = currentNode.leftTree;
            }else if(key > currentNode.key){
                //大
                currentNode = currentNode.rightTree;
            }else{ //key == currentNode.key 返回true
                return true;
            }
        }
        return false;
    }


    //前序遍历
    BinarySearchTree.prototype.preOrderTraversal = function(){
        this.preOrderTraversalNode(this.root)
    }

    BinarySearchTree.prototype.preOrderTraversalNode = function(node){
        if(node){
            console.log(node.key)
            this.preOrderTraversalNode(node.leftTree);
            this.preOrderTraversalNode(node.rightTree);
        }
    }

    //中序遍历
    BinarySearchTree.prototype.middleTraversal = function(){
        this.middleTraversalNode(this.root)
    }

    BinarySearchTree.prototype.middleTraversalNode = function(node){
        if(node){
            this.middleTraversalNode(node.leftTree);
            console.log(node.key);
            this.middleTraversalNode(node.rightTree);
        }
    }

    //后序遍历
    BinarySearchTree.prototype.backTraversal = function(){
        this.backTraversalNode(this.root)
    }

    BinarySearchTree.prototype.backTraversalNode = function(node){
        if(node){
            this.backTraversalNode(node.leftTree);
            this.backTraversalNode(node.rightTree);
            console.log(node.key);
        }
    }

    //寻找节点的后继
    BinarySearchTree.prototype.getSuccessor = function(node){
        let successorParent = node;
        let successor= node;
        let currentNode = node.rightTree;//在节点的右子树中查找
        while(currentNode){
            successorParent = successor;
            successor = currentNode;
            currentNode = currentNode.left;//找节点的右子树中的最小值
        }
        if(successor !== node.rightTree){
            successorParent.leftTree = successor.rightTree;
            successor.rightTree=node.rightTree
        }
        return successor;
    }


    //删除节点
    BinarySearchTree.prototype.delete = function(key){
        let delNode = this.searchNode(key);
        this.removeNode(delNode);
    }
    BinarySearchTree.prototype.removeNode = function (delNode) {
        let currentNode = this.root;
        let parentNode = this.root;
        let isLeftTree = true;
        //0.查找节点
        while (currentNode.key !== delNode.key){
            parentNode = currentNode;
            if(currentNode.key < delNode.key){
                //如果当前节点比要删除的节点的键值大 说明要删除的节点在当前节点的右子树上
                //继续向右子树查找
                isLeftTree = false;
                currentNode = currentNode.rightTree;
            }else {
                //说明当前节点的键值比要删除的键值大,说明要删除的节点在当前节点的左子树上
                isLeftTree =true;
                currentNode = currentNode.leftTree;
            }
            //如果currentNode指向null,说明没有找到要删除的元素
            if(currentNode.leftTree ==null && currentNode.rightTree == null) return false;
        }
        //1.情况1:要删除的节点是叶子节点
        if(delNode.leftTree == null && delNode.rightTree == null){
            //如果只有一个根节点
            if(delNode === this.root){
                this.root = null;//设置为空树
            }else if(isLeftTree){
                parentNode.leftTree = null
            }else{
                parentNode.rightTree = null
            }
        }

        //2.情况2:要删除的节点只有左子树或者只有右子树
        else if(delNode.rightTree == null){

            if(delNode == this.root){
                //如果要删除的节点是根节点,只有一个左子树
                delNode.leftTree = this.root
            }
            else if(isLeftTree){
                //要删除的节点只有子左子树 要其父节点的子树指向它的左子树
                parentNode.leftTree = delNode.leftTree
            }else{
                parentNode.rightTree - delNode.leftTree
            }
        }else if(delNode.leftTree == null){
            if(delNode == this.root){
                this.root = currentNode.rightTree
            }else if(isLeftTree){
                parentNode.leftTree = delNode.rightTree
            }else{
                parentNode.rightTree = delNode.rightTree
            }
        }
        //3.情况3.要删除的节点左右子树都有 找后继
        else{
            let successor = this.getSuccessor(delNode);
            if(this.root == delNode){
                this.root = successor;
            }else{
                if(isLeftTree){
                    parentNode.leftTree =successor;
                }else{
                    parentNode.rightTree = successor;
                }
            }
            successor.leftTree = delNode.leftTree
        }
    }
}

Balanced binary tree

Solve binary search tree in the left and right child nodes for possible data imbalance in the
non-balanced binary tree search efficiency is O (N)
search efficiency balanced binary tree is O (logN)
nature red-black tree:

  1. Node is black and red
  2. The root node is black
  3. Each leaf node are black empty node NULL
  4. Two child nodes of each node are black red (not all red two consecutive nodes on the path from the root to each leaf)
  5. All the paths of any node to its leaf nodes contain the same number of black nodes
  6. All paths from the root to leaf nodes, the longest path will not be more than twice the shortest path
  7. To maintain a balance of three ways: color / rotate left / right rotation
Published 139 original articles · won praise 1 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_42139212/article/details/104585857