JS实现平衡二叉树

JS实现平衡二叉树

废话不多说我直接上撸代码,喜欢的直接拷走即可使用,有问题请留言,转载请注明出处。

代码

class AVLTree {
    constructor(num) {
        // this.root = {};
        this.value = num;
        this.height = 1;
        this.leftChild = null;
        this.rightChild = null;
    }

    addNum(num) {
        let result = this;
        let point = new AVLTree(num); //创建节点 每一个节点都是一颗树
        if (point.value > this.value) { 
            if (this.rightChild == null) {
                this.rightChild = point;
            } else {
                result.rightChild = this.rightChild.addNum(num);
            }
            let balanceFactor = this.getBalance(this.rightChild, this.leftChild); //该树下面的左右节点平衡值
            if (balanceFactor == 2) { //差值过大 不平衡
                if (point.value > this.rightChild.value) {
                    result = this.RR();
                } else {
                    result = this.RL();
                }
            }
        } else if (point.value < this.value) {
            if (this.leftChild == null) {
                this.leftChild = point;
            } else {
                result.leftChild = this.leftChild.addNum(num);
            }
            let balanceFactor = this.getBalance(this.leftChild, this.rightChild);
            if (balanceFactor == 2) {
                if (point.value < this.leftChild.value) {
                    result = this.LL();
                } else {
                    result = this.LR();
                }
            }

        } else {
            throw '输入了重复的值'
        }
        this.height = this.getMax(this.leftChild, this.rightChild) + 1;
        return result;
    }

    deleteNum(num) {
        var result = this;
        if (num > this.value) {
            result.rightChild = this.rightChild.deleteNum(num);
        } else if (num < this.value) {
            result.leftChild = this.leftChild.deleteNum(num);
        } else {
            if (num !== this.value) {
                throw '输入了没有的值';
            }
            if (result.leftChild !== null) {
                let current = result.leftChild;
                while (true) { //不停的找到左节点的最右子节点 到底
                    if (current.rightChild) {
                        current = current.rightChild
                    } else {
                        break;
                    }
                } 
                result.value = current.value;
                result.leftChild = result.leftChild.deleteNum(current.value);
            } else if (result.rightChild !== null) {
                let current = result.rightChild;
                while (true) {
                    if (current.leftChild) {
                        current = current.leftChild
                    } else {
                        break;
                    }
                }
                result.value = current.value;
                result.rightChild = result.rightChild.deleteNum(current.value);
            } else {
                console.log('delete' + result); // 最后子叶节点
                return null;
            }
        }

        if (result.getBalance(result.leftChild, result.rightChild) == 2) {//再平衡
            if (result.getHeight(result.leftChild.rightChild) - result.getHeight(result.leftChild.leftChild) == 1) {
                result = result.LR();
            } else {
                result = result.LL();
            }
        } else if (result.getBalance(result.leftChild, result.rightChild) == -2) {
            if (result.getHeight(result.rightChild.leftChild) - result.getHeight(result.rightChild.rightChild) == 1) {
                result = result.RL();
            } else {
                result = result.RR();
            }
        } else {
            console.log('is balance')
        }
        result.height = this.getMax(this.leftChild, this.rightChild) + 1;
        return result

    }
    getMax(a, b) {
        let aHeight, bHeight;
        if (!a) {
            aHeight = 0;
        } else {
            aHeight = a.height;
        }
        if (!b) {
            bHeight = 0
        } else {
            bHeight = b.height;
        }
        return aHeight > bHeight ? aHeight : bHeight;
    }
    getBalance(a, b) {
        let aValue, bValue;
        if (!a) {
            aValue = 0;
        } else {
            aValue = a.height;
        }
        if (!b) {
            bValue = 0
        } else {
            bValue = b.height;
        }
        return aValue - bValue;
    }
    getHeight(a) {
        if (a) {
            return a.height;
        }
        return 0;
    }
    RR() {
        let a = this;
        let b = this.rightChild;
        a.rightChild = b.leftChild;
        b.leftChild = a;
        a.height = a.getMax(a.rightChild, a.leftChild) + 1;
        b.height = b.getMax(b.rightChild, b.rightChild) + 1;
        return b;
    }
    RL() {
        let a = this;
        a.rightChild = a.rightChild.LL();
        a = a.RR();
        return a;

    }
    LL() {
        let a = this;
        let b = this.leftChild;
        a.leftChild = b.rightChild;
        b.rightChild = a;
        a.height = a.getMax(a.rightChild, a.leftChild) + 1;
        b.height = b.getMax(b.rightChild, b.rightChild) + 1;
        return b;

    }
    LR() {
        let a = this;
        a.leftChild = a.leftChild.RR();
        a = a.LL();
        return a;

    }
}

//使用方法
function createTree(arr) {
    let result;
    arr.forEach((child, index) => {
        if (index === 0) {
            result = new AVLTree(child);
        } else {
            result = result.addNum(child);
        }
    })
    return result;
}
var arr = [1, 3, 5, 7, 15, 24, 56, 11, 33, 42, 2, 4, 6, 12];
var tree = createTree(arr);
下面是结果图

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值