数据结构与算法-二叉搜索树封装

直接干代码

/**
 *
 * 二叉搜索树封装
 *
 * */

function BinarySearchTree(){

    this.root = null;


    function Node(key){
        this.key = key;
        this.left = null;
        this.right = null;
    }

    //插入新节点
    BinarySearchTree.prototype.insert = function (key){
        let newNode = new Node(key);
        if (this.root == null){
            this.root = newNode;
            return true;
        }
        let current = this.root;
        let i = 0;
        while (true){
            i++;
            if (current.key === key) return false;
            if (current.key < key){
                if (current.right == null){
                    current.right = newNode;
                    return true;
                }
                current = current.right;
            }else {
                if (current.left == null){
                    current.left = newNode;
                    return true;
                }
                current = current.left;
            }
        }
    }

    //查找节点
    BinarySearchTree.prototype.search = function (key){
        if (this.root == null) return false;
        let current = this.root;
        while (current.key != key){
            if (current.key > key) current = current.left;
            else if (current.key < key) current = current.right;
            if (current == null) return false;
        }
        return true;
    }

    //删除节点
    BinarySearchTree.prototype.delete = function (key){
        if (this.root == null) return false;
        let parent = this.root;
        let current = this.root;
        let isLeftNode = true;
        //找到目标节点
        while (current.key != key){
            parent = current;
            if (current.key > key) {
                isLeftNode = true;
                current = current.left;
            }
            else if (current.key < key) {
                isLeftNode = false;
                current = current.right;
            }
            //找不到返回false
            if (current == null) return false;
        }

        //找到后分三种情况



        if (current.left == null && current.right == null){
        //1、删除叶子节点
            //1.1若current为根节点root
            if (current == this.root) this.root = null;
            //1.2若current为左节点
            else if (isLeftNode) parent.left = null;
            //1.3若current为右节点
            else parent.right = null;

        }else if(current.left == null){
        //2、删除只有一个叶子节点的节点
            //若current.left == null

            //2.1若current为根节点root
            if (current == this.root) this.root = current.right;
            //2.2若current为父节点且子节点在左边
            else if (isLeftNode) parent.left = current.right;
            //2.3若current为父节点且子节点在右边
            else parent.right = current.right;

        }else if (current.right == null){
            //若current.left == null
            //2.4若current为根节点root
            if (current == this.root) this.root = current.left;
            //2.5若current为父节点且子节点在左边
            else if (isLeftNode) parent.left = current.left;
            //2.6若current为父节点且子节点在右边
            else parent.right = current.left;

        }else{
        //3、删除有两个叶子节点的节点
            //1.获取后继节点
            let successor = this.getSuccessor(current)

            //2.判断是否根节点
            if (current == this.root) {
                this.root = successor
            }else if (isLeftNode){
                parent.left = successor
            }else{
                parent.right = successor
            }

            //3.将后继的左子节点改为被删除节点的左子节点
            successor.left = current.left
        }
        return true;
    }

    //封装查找后继的方法
    BinarySearchTree.prototype.getSuccessor = function(delNode){
        //1.定义变量,保存找到的后继
        let successor = delNode
        let current = delNode.right
        let successorParent = delNode

        //2.循环查找current的右子树节点
        while(current != null){
            successorParent = successor
            successor = current
            current = current.left
        }

        //3.判断寻找到的后继节点是否直接就是删除节点的right节点
        if(successor != delNode.right){
            successorParent.left = successor.right
            successor.right = delNode.right
        }
        return successor
    }




    //最大值
    BinarySearchTree.prototype.Max = function (){
        if (this.root == null) return null;
        let current = this.root;
        while (current.right){
            current = current.right;
        }
        console.log(current);
        return current.key;
    }

    //最小值
    BinarySearchTree.prototype.Min = function (){
        if (this.root == null) return null;
        let current = this.root;
        while (current.left){
            current = current.left;
        }
        console.log(current);
        return current.key;
    }

    /**
     *
     * 树的遍历
     *
     * */

    /**
     * 1、前序遍历
     * 先序遍历的过程为:
         首先,遍历根节点;
         然后,遍历其左子树;
         最后,遍历其右子树;
     */
    BinarySearchTree.prototype.preOrderTraversal = function (handler){
        this.preOrderNode(this.root,handler);
    }

    BinarySearchTree.prototype.preOrderNode = function (node,handler){
        if (node != null){
            //处理节点
            handler(node.key);
            //遍历左子树
            this.preOrderNode(node.left,handler);
            //遍历右子树
            this.preOrderNode(node.right,handler);
        }
    }


    /**
     * 2、中序遍历
     * 先序遍历的过程为:
         首先,遍历其左子树;
         然后,遍历根(父)节点;
         最后,遍历其右子树;
     */
    BinarySearchTree.prototype.midOrderTraversal = function (handler){
        this.midOrderNode(this.root,handler);
    }

    BinarySearchTree.prototype.midOrderNode = function (node,handler){
        if (node != null){
            //遍历左子树
            this.midOrderNode(node.left,handler);
            //处理节点
            handler(node.key);
            //遍历右子树
            this.midOrderNode(node.right,handler);
        }
    }

    /**
     * 3、后序遍历
     * 先序遍历的过程为:
         首先,遍历其左子树;
         然后,遍历其右子树;
         最后,遍历根(父)节点;
     */
    BinarySearchTree.prototype.postOrderTraversal = function (handler){
        this.postOrderNode(this.root,handler);
    }

    BinarySearchTree.prototype.postOrderNode = function (node,handler){
        if (node != null){
            //遍历左子树
            this.postOrderNode(node.left,handler);
            //遍历右子树
            this.postOrderNode(node.right,handler);
            //处理节点
            handler(node.key);
        }
    }






}

let searchTree = new BinarySearchTree();

let strTree = '';

function handler(str){
    strTree += str+" ";
}

console.log("---------------插入------------------")
console.log(searchTree.insert(5));
console.log(searchTree.insert(9));
console.log(searchTree.insert(3));
console.log(searchTree.insert(2));
console.log(searchTree.insert(1));
console.log(searchTree.insert(10));
console.log(searchTree.insert(11));
console.log(searchTree.insert(13));
console.log(searchTree.insert(8));
console.log(searchTree.insert(4));


console.log(searchTree.insert(4));
console.log(searchTree.root);

console.log("--------------------查询--------------------")
console.log(searchTree.search(10));
console.log(searchTree.search(8));
console.log(searchTree.search(1));
console.log(searchTree.search(16));


console.log("--------------------最值--------------------")
console.log("最大值:"+searchTree.Max());
console.log("最小值:"+searchTree.Min());

console.log("--------------------先序遍历--------------------")
searchTree.preOrderTraversal(handler);
console.log("先序遍历",strTree);
strTree = "";


console.log("--------------------中序遍历--------------------")
searchTree.midOrderTraversal(handler);
console.log("中序遍历",strTree);
strTree = "";

console.log("--------------------后序遍历--------------------")
searchTree.postOrderTraversal(handler);
console.log("后序遍历",strTree);
strTree = "";


// console.log("--------------------移除只有一个子节点的节点--------------------")
// console.log(searchTree.delete(10));
// console.log(searchTree.root)

// console.log("--------------------移除叶子节点--------------------")
// console.log(searchTree.delete(4));
// console.log(searchTree.delete(13));
// console.log(searchTree.root)
//
//
//
console.log("--------------------移除父节点节点--------------------")
console.log(searchTree.delete(5));
console.log(searchTree.delete(9));
console.log(searchTree.root)

测试结果

在这里插入图片描述


posted on 2021-06-19 20:47  千里码!  阅读(16)  评论(0)    收藏  举报  来源