首页 > 其他分享 >JS AVL树(数据结构)- 笔记

JS AVL树(数据结构)- 笔记

时间:2024-03-24 13:12:12浏览次数:19  
标签:node right val .# null JS AVL 数据结构 left

Code: 

/**
 * AVL 树
 * @class
 */
class AVLTree {
    /**
     * @type {TreeNode}
     */
    #root;

    /**
     * @constructor
     */
    constructor() {
        this.#root = null;
    }

    /**
     * 获取节点高度
     * @param {TreeNode} node 
     */
    height(node) {
        // 空节点高度为-1
        return node === null ? -1 : node.height;
    }

    /**
     * 更新节点高度
     * @param {TreeNode} node 
     */
    #updateHeight(node) {
        // 当前节点的高度等于最高子树的高度 + 1
        node.height = Math.max(this.height(node.left), this.height(node.right)) + 1;
    }

    /**
     * 获取平衡因子
     * @param {TreeNode} node 
     * @returns 
     */
    getBalanceFactor(node) {
        // 空节点平衡因子为 0 
        if (node === null) {
            return 0;
        }
        // 节点平衡因子 = 左子树高度 - 右子树高度
        return this.height(node.left) - this.height(node.right);
    }

    /**
     * 右旋
     * @param {TreeNode} node 
     */
    #rightRotate(node) {
        const child = node.left;
        const grandChild = child.right;
        child.right = node;
        node.left = grandChild;
        this.#updateHeight(node);
        this.#updateHeight(child);

        return child;
    }

    /**
     * 左旋
     * @param {TreeNode} node 
     */
    #leftRotate(node) {
        const child = node.right;
        const grandChild = child.left;
        child.left = node;
        node.right = grandChild;
        this.#updateHeight(node);
        this.#updateHeight(child);

        return child;
    }

    /**
     * 旋转节点使其平衡
     * @param {TreeNode} node 
     */
    #rotate(node) {
        const factor = this.getBalanceFactor(node);
        // 左偏
        if (factor > 1) {
            // 直接右旋
            if (this.getBalanceFactor(node.left) >= 0) {
                return this.#rightRotate(node);
            }
            // 先左旋后右旋
            node.left = this.#leftRotate(node.left);
            return this.#rightRotate(node);
        }
        // 右偏
        if (factor < -1) {
            // 直接左旋
            if (this.getBalanceFactor(node.right) <= 0) {
                return this.#leftRotate(node.right);
            }
            // 先右旋后左旋
            node.right = this.#rightRotate(node.right);
            return this.#leftRotate(node);
        }

        return node;
    }

    /**
     * 辅助节点的插入
     * @param {TreeNode} node 
     * @param {number} val 
     */
    #insertHelper(node, val) {
        if (node === null) {
            return new TreeNode(val);
        }
        if (val === node.val) {
            return node;
        }
        if (val < node.val) {
            node.left = this.#insertHelper(node.left, val);
        }
        else if (val > node.val) {
            node.right = this.#insertHelper(node.right, val);
        }
        this.#updateHeight(node);
        node = this.#rotate(node);

        return node;
    }

    /**
     * 插入节点
     * @param {number} val 
     */
    insert(val) {
        this.#root = this.#insertHelper(this.#root, val);
    }

    /**
     * 辅助节点的删除
     * @param {TreeNode} node 
     * @param {number} val 
     */
    #removeHelper(node, val) {
        if (node === null) {
            return null;
        }
        if (val < node.val) {
            node.left = this.#removeHelper(node.left, val);
        }
        else if (val > node.val) {
            node.right = this.#removeHelper(node.right, val);
        }
        else {
            if (node.left === null || node.right === null) {
                const child = node.left === null ? node.right : node.left;
                if (child === null) {
                    return null;
                }
                node = child;
            }
            else {
                let tmp = node.right;
                while(tmp.left !== null) {
                    tmp = tmp.left;
                }
                node.right = this.#removeHelper(node.right, tmp.val);
                node.val = tmp.val;
            }
        }
        this.#updateHeight(node);
        node = this.#rotate(node);

        return node;
    }

    /**
     * 删除节点
     * @param {number} val 
     */
    remove(val) {
        this.#root = this.#removeHelper(this.#root, val);
    }

    /**
     * 查找节点
     * @param {number} val 
     * @returns 
     */
    search(val) {
        let cur = this.#root;
        while (cur !== null) {
            if (cur.val < val) {
                cur = cur.right;
            }
            else if (cur.val > val) {
                cur = cur.left;
            }
            else {
                break;
            }
        }

        return cur;
    }
}

/**
 * 树节点
 * @class
 */
class TreeNode {
    val;
    left;
    right;
    height;
    constructor(val, left, right) {
        this.val = val === undefined ? 0 : val;
        this.left = left === undefined ? left : null;
        this.right = right === undefined ? right : null;
        this.height = height === undefined ? 0 : height;
    }
}

 

标签:node,right,val,.#,null,JS,AVL,数据结构,left
From: https://www.cnblogs.com/fanqshun/p/18092297

相关文章

  • JS 二叉搜索树
    Code:classTreeNode{val;left;right;constructor(val,left,right){this.val=val??0;this.left=left?left:null;this.right=right?right:null;}}/***二叉搜索树*/classBinarySearchTree{......
  • java数据结构与算法刷题-----LeetCode75. 颜色分类
    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846文章目录1.双指针两次遍历2.三指针1.双指针两次遍历解题思路:时间复杂度O(......
  • java数据结构与算法刷题-----LeetCode451. 根据字符出现频率排序
    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846文章目录1.hash统计出现次数后排序2.桶排序1.hash统计出现次数后排序解题思路:时间复杂度O(......
  • js一些底层
    简介:JavaScript是一种高级编程语言,通常在网页开发中用于前端和后端开发。JavaScript的底层实现是浏览器或服务器上的JavaScript引擎。不同的引擎可能有不同的底层实现,但它们都有一个共同的目标,即执行JavaScript代码。JavaScript的底层实现涉及到多个方面,包括解释器、......
  • React&Nest.js社区平台(四)——✏️文章发布与管理实战
    公众号:【可乐前端】,每天3分钟学习一个优秀的开源项目,分享web面试与实战知识。前言在上一期我们已经实现了个人信息模块,这一期来实现文章发布与管理。涉及到如下功能:草稿创建/修改文章发布文章删除获取我发布的文章看起来像是文章的增删改查功能,其实还是有不少值得思考......
  • Python数据结构实验 队列的实现
    一、实验目的1.掌握用Python定义队列的顺序存储结构和链式存储结构,以便在实际背景下灵活运用;2.掌握队列的特点,即先进先出的原则;3.掌握队列的基本操作实现方法。二、实验环境1.Windows操作系统的计算机2.Python3.7环境平台和PyCharm编辑器三、实验说明 1.实现队列的顺序存......
  • 【附源码】Node.js毕业设计高校拼车系统(Express)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着社会的发展与科技的进步,人们对于出行方式的需求日益多样化,尤其是在高校校园内,学生、教职工等群体的出行需求频繁而复杂。传统的出行方式如步行、自行车......
  • 【附源码】Node.js毕业设计高校排课系统设计(Express)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着信息技术的飞速发展,高校教育管理逐渐向数字化、智能化方向迈进。在这一背景下,高校排课系统作为教育管理的重要组成部分,其优化与改进显得尤为重要。传统......
  • vue2 在 main.js 中定义全局函数,在二次封装的 api\index.js 中引用全局函数 GPT4 Tur
    在Vue2中,你可以通过Vue的原型系统来定义全局函数,然后在整个应用的任何组件中使用这些函数。同样,你也可以在其他JavaScript文件中使用这些函数,比如你提到的二次封装的API文件。下面是如何实现这一过程的步骤:###第一步:在`main.js`中定义全局函数在Vue项目的入口文件`main.js`中,你......
  • Python 潮流周刊第 43 期(摘要),赠书 5 本《Python数据结构与算法分析(第3版)》
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。周刊全文:https://pythoncat.top/posts/2024-03-23-weekly特别提醒:本期赠书5......