javascript 数据结构专题--二叉树基本操作

基本结构

创建 插入 删除 查找 遍历 深度

// 二叉树有一个特殊性:相对本节点较小的值保存在左节点,相对本节点较大的值保存在右节点,该特性能让查值效率提高

//创建结点
function Node(data, left, right) {
    this.data = data;
    this.left = left;
    this.right = right;
}
//展示结点数据
Node.prototype = {
    show: function () {
        console.log(this.data);
    }
}
//树构造函数
function Tree() {
    this.root = null;
}
Tree.prototype = {
//插入
// 二叉树有一个<b>特殊性:相对本节点较小的值保存在左节点,
//相对本节点较大的值保存在右节点</b>,该特性能让查值效率提高
    insert: function (data) {
        var node = new Node(data, null, null);
        if(!this.root) {
            this.root = node;
            return;
        }
        var current = this.root;
        var parent = null;
        while (current) {
            parent = current;
            if (data < parent.data) {
                current = current.left;
                if(!current) {
                    parent.left  = node;
                    return;
                }
            } else {
                current = current.right;
                if(!current) {
                    parent.right = node;
                    return;
                }
            }
        }
    },
    //删除操作稍微复杂一些。思路在于首先找到删除值的结点,若该结点是叶子结点,则直接将其置为null,
//若其具有左子树或右子树,则将左孩子结点或右孩子结点赋值给当前结点。
//若当前结点既有左子树,又有右子树,则在其左子树中,寻找一个和当前结点值最接近的孩子结点(即中序遍历结果中当前结点的前驱),
//将当前结点的值替换为该孩子结点的值,替换后,树中此时就有两个重复的值,因此,再利用递归删除重复的孩子结点,依次类推。。。

// 从待删除节点的左子树找节点值最大的节点A,替换待删除节点,并删除节点A;
// 从待删除节点的右子树找节点值最小的节点A,替换待删除节点,并删除节点A。
// 为什么要找右子树最小值(或者左子树的最大值)呢?因为右子树最小值比左子树的所有值都大,却比右子树的所有值小,这正是根节点的特性,用它来替代根节点再适合不过了。
    delete: function(root, data) {
       if(!root) {
           console.log("删除失败")
           return root;
       }
       if(data < root.data) {//若当前结点值大于删除值,则继续在左子树中寻找删除值
           root.left = this.delete(root.left, data)
       } else if (data > root.data) {//若当前结点值小于删除值,则继续在右子树中寻找删除值
           root.right = this.delete(root.right, data)
       } else {找到与删除中相等的结点
          if(root.left === null && root .right === null) {//叶子结点
            root = null;
          } else if(root.left === null) {//只有右子树
            root = root.right
          } else if(root.right === null) {//只有左子树
            root = root.left
          } else {//同时具有左右子树
            let prevNode = root.left;
            while(prevNode.right) {//寻找不大于当前结点值的最大结点值
                prevNode = prevNode.right
            }
            root.data = prevNode.data //替换值
            root.left = this.delete(root.left, prevNode.data);//递归左子树,删除重复值的结点
          }
       }
       return root
    },
    //前序遍历
    preOrder: function (node) {
        if (node) {
            node.show();
            this.preOrder(node.left);
            this.preOrder(node.right);
        }
    },
    //中序遍历
    middleOrder: function (node) {
        if (node) {
            this.middleOrder(node.left);
            node.show();
            this.middleOrder(node.right);
        }
    },
    //后序遍历
    laterOrder: function (node) {
        if(node) {
            this.laterOrder(node.left);
            this.laterOrder(node.right);
            node.show();
        }
    },
    //获取最小值
    getMin: function () {
        var current = this.root;
        while(current) {
            if(!current.left) {
                return current
            }
            current = current.left;
        }
    },
    //获取最大值
    getMax: function () {
        var current = this.root;
        while(current) {
            if(!current.right) {
                return current;
            }
            current = current.right;
        }
    },
    //获取深度
    getDeep: function (node, deep) {
        deep = deep || 0;
        if(node == null) {
            return deep;
        }
        deep++;
        var dleft = this.getDeep(node.left, deep);
        var dright = this.getDeep(node.right, deep);
        return Math.max(dleft, dright);
    },
    //查找结点
    getNode: function (data, node) {
        if(node) {
            if(node) {
                if(data === node.data) {
                    return node;
                } else if (data < node.data) {
                    return this.getNode(data, node.left);
                } else {
                    return this.getNode(data, node.right);
                }
            }
        } else {
            return null
        }
    }

}
var t = new Tree();
t.insert(3);
t.insert(9);
t.insert(1);
t.insert(8);
t.insert(2);
t.insert(7);
t.insert(4);
t.insert(5);
t.insert(0);
console.log(t);
t.middleOrder(t.root);
console.log("MIN/n", t.getMin(), "MAX/n", t.getMax(), "DEEP", t.getDeep(t.root, 0), "getNode", t.getNode(5,t.root))

上一篇 javascript 数据结构专题–二叉树概览

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值