Javascript数据结构——二叉查找树的实现(超详细代码)

定义:二叉查找树又被称为二叉搜索树。设x为二叉查找树中的一个结点,x结点包含关键字value,结点x的key值计为value[x]。如果y是x的左子树中的一个结点,则value[y]<=value[x];如果y是x的右子树的一个结点,则value[y]>=value[x]。

在二叉查找树中:

(1)若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值。

(2)任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。

(3)任意结点的左、右子树也分别为二叉查找树。

(4)没有键值相等的结点。

    //封装二叉树的方法
    function BinarySearchTree() {
        //封装节点
        function Node(key) {
            this.key = key;
            this.left = null;
            this.right = null;
        }

        //属性
        this.root = null;

        //方法
        //二叉树插入数据的方法
        BinarySearchTree.prototype.insert = function (key) {
            //1.根据key创建新的节点
            var newNode = new Node(key);

            //2.判断根节点是否有值
            if (this.root === null) {//根节点没有值,就先新建根节点
                this.root = newNode;
            } else { 
                //调用插入节点的方法
                this.insertNode(this.root, newNode);
            }
        };

        //类内部使用的方法,插入节点
        BinarySearchTree.prototype.insertNode = function (node, newNode) {
            //将之前的节点与新节点做比较
            if (newNode.key < node.key) {
                //新节点的key小于上一节点的key,向左查找
                //如果旧节点的左孩子为空,将新节点插入到此处
                //否则递归向左查找直到旧节点的左孩子为空
                if (node.left === null) {
                    node.left = newNode;
                } else {
                    this.insertNode(node.left, newNode);
                }
            } else {//向右查找
                if (node.right === null) {
                    node.right = newNode;
                } else {
                    this.insertNode(node.right, newNode)
                }
            }
        };

        //树的遍历
        //1.先序遍历
        BinarySearchTree.prototype.preOrderTraversal = function () {
            this.preOrderTraversalNode(this.root)
        };
        BinarySearchTree.prototype.preOrderTraversalNode = function (node) {
            if (node !== null) {
                //1.处理先序遍历经过的节点
                preResult += node.key + ' ';
                //2.查找经过节点的左子节点
                this.preOrderTraversalNode(node.left);
                //3.查找经过节点的右子节点
                this.preOrderTraversalNode(node.right);
            }
        };

        //2.中序遍历
        BinarySearchTree.prototype.midOrderTraversal = function () {
            this.midOrderTraversalNode(this.root);
        };
        BinarySearchTree.prototype.midOrderTraversalNode = function (node) {
            if (node !== null) {
                //1.查找经过节点的左子节点
                this.midOrderTraversalNode(node.left);
                //2.处理节点
                midResult += node.key + ' ';
                //3.查找经过节点的右子节点
                this.midOrderTraversalNode(node.right);
            }
        };
        //3.后序遍历
        BinarySearchTree.prototype.postOrderTraversal = function () {
            this.postOrderTraversalNode(this.root);
        };
        BinarySearchTree.prototype.postOrderTraversalNode = function (node){
            if (node !== null) {
                //1.查找经过节点的左子节点
                this.postOrderTraversalNode(node.left);
                //2.查找经过节点的右子节点
                this.postOrderTraversalNode(node.right);
                //3.处理节点
                postResult += node.key + ' ';
            }
        };

        //寻找最值
        //寻找最大值
        BinarySearchTree.prototype.max = function () {
            //从根节点开始
            var node = this.root;
            var key = null;
            //依此向右不断的查找,直到节点为null
            while (node) {
                key = node.key;
                node = node.right;
            }
            return key;
        };

        //寻找最小值
        BinarySearchTree.prototype.min = function () {
            //从根节点开始
            var node = this.root;
            var key = null;
            //依此向左不断的查找,直到节点为null
            while (node) {
                key = node.key;
                node = node.left;
            }
            return key;
        };

        //使用递归  搜索特定的值
        BinarySearchTree.prototype.search_DG = function (key) {
            return this.searchNode_DG(this.root, key);
        };
        BinarySearchTree.prototype.searchNode_DG = function (node, key) {
            //1.如果传入的node为null,退出递归
            if (node === null) {
                return false;
            }
            //2.判断node节点的值和传入key大小
            if (node.key > key) {
                return this.searchNode_DG(node.left, key);
            } else if (node.key < key) {
                return this.searchNode_DG(node.right, key);
            } else {//相同,说明找到了key
                return true;
            }
        };

        //使用循环  搜索特定的值
        BinarySearchTree.prototype.search_Loop = function (key) {
            var node = this.root;
            while (node) {
                if (key < node.key) { //向左查找
                    node = node.left;
                } else if (key > node.key) {
                    node = node.right;
                } else {
                    return true;
                }
            }
            return false;  //while循环退出=>node为null=>查找失败
        }
    }

下面对代码进行验证:

    //创建二叉搜索树 BinarySearchTree
    var bst = new BinarySearchTree();
    //2.插入数据
    bst.insert(11);
    bst.insert(7);
    bst.insert(15);
    bst.insert(5);
    bst.insert(3);
    bst.insert(9);
    bst.insert(8);
    bst.insert(10);
    bst.insert(13);
    bst.insert(12);
    bst.insert(14);
    bst.insert(20);
    bst.insert(18);
    bst.insert(25);
    bst.insert(6);
    preResult = '';
    bst.preOrderTraversal();//测试先序遍历
    console.log('先序遍历', preResult);

    midResult = '';
    bst.midOrderTraversal();//测试中序遍历
    console.log('中序遍历', midResult);

    postResult = '';
    bst.postOrderTraversal();//测试后序遍历
    console.log('后序遍历', postResult);

    //测试最值
    console.log('最大值', bst.max());
    console.log('最小值', bst.min());

    //测试查找特定值
    console.log(bst.search_DG(12));
    console.log(bst.search_Loop(13));
    console.log(bst.search_Loop(2));

输入的节点数据依次是11 7 15 5 3 9 8 10 13 12 14 20 18 25 6。能够得到如下二叉查找树:
在这里插入图片描述
最后检查一下控制台的输出:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值