AVLTree 类

avltree 类

avltree类扩展了bst类以重写insertdelete方法以在必要时重新平衡树。下面的代码给出了 avltree 类的完整源代码。

package demo;public class AVLTree<E extends Comparable> extends BST {    /** Create an empty AVL tree */    public AVLTree() {}    /** Create an AVL tree from an array of objects */    public AVLTree(E[] objects) {        super(objects);    }    @Override /** Override createNewNode to create an AVLTreeNode */    protected AVLTreeNode createNewNode(E e) {        return new AVLTreeNode(e);    }    @Override /** Insert an element and rebalance if necessary */    public boolean insert(E e) {        boolean successful = super.insert(e);        if (!successful)            return false; // e is already in the tree        else {            balancePath(e); // Balance from e to the root if necessary        }        return true; // e is inserted    }    /** Update the height of a specified node */    private void updateHeight(AVLTreeNode node) {        if (node.left == null && node.right == null) // node is a leaf            node.height = 0;        else if (node.left == null) // node has no left subtree            node.height = 1 + ((AVLTreeNode)(node.right)).height;        else if (node.right == null) // node has no right subtree            node.height = 1 + ((AVLTreeNode)(node.left)).height;        else            node.height = 1 + Math.max(((AVLTreeNode)(node.right)).height, ((AVLTreeNode)(node.left)).height);    }    /** Balance the nodes in the path from the specified    * node to the root if necessary    */    private void balancePath(E e) {        java.util.ArrayList<TreeNode> path = path(e);        for (int i = path.size() - 1; i >= 0; i--) {            AVLTreeNode A = (AVLTreeNode)(path.get(i));            updateHeight(A);            AVLTreeNode parentOfA = (A == root) ? null : (AVLTreeNode)(path.get(i - 1));            switch (balanceFactor(A)) {            case -2:                if (balanceFactor((AVLTreeNode)A.left) <= 0) {                    balanceLL(A, parentOfA); // Perform LL rotation                }                else {                    balanceLR(A, parentOfA); // Perform LR rotation                }                break;                case +2:                    if (balanceFactor((AVLTreeNode)A.right) >= 0) {                        balanceRR(A, parentOfA); // Perform RR rotation                    }                else {                    balanceRL(A, parentOfA); // Perform RL rotation                }            }        }    }    /** Return the balance factor of the node */    private int balanceFactor(AVLTreeNode node) {        if (node.right == null) // node has no right subtree            return -node.height;        else if (node.left == null) // node has no left subtree            return +node.height;        else            return ((AVLTreeNode)node.right).height - ((AVLTreeNode)node.left).height;    }    /** Balance LL (see Figure 26.2) */    private void balanceLL(TreeNode A, TreeNode parentOfA) {        TreeNode B = A.left; // A is left-heavy and B is left-heavy        if (A == root) {            root = B;        }        else {            if (parentOfA.left == A) {                parentOfA.left = B;            }            else {                parentOfA.right = B;            }        }        A.left = B.right; // Make T2 the left subtree of A        B.right = A; // Make A the left child of B        updateHeight((AVLTreeNode)A);        updateHeight((AVLTreeNode)B);    }    /** Balance LR (see Figure 26.4) */    private void balanceLR(TreeNode A, TreeNode parentOfA) {        TreeNode B = A.left; // A is left-heavy        TreeNode C = B.right; // B is right-heavy        if (A == root) {            root = C;        }        else {            if (parentOfA.left == A) {                parentOfA.left = C;            }            else {                parentOfA.right = C;            }        }        A.left = C.right; // Make T3 the left subtree of A        B.right = C.left; // Make T2 the right subtree of B        C.left = B;        C.right = A;        // Adjust heights        updateHeight((AVLTreeNode)A);        updateHeight((AVLTreeNode)B);        updateHeight((AVLTreeNode)C);    }    /** Balance RR (see Figure 26.3) */    private void balanceRR(TreeNode A, TreeNode parentOfA) {        TreeNode B = A.right; // A is right-heavy and B is right-heavy        if (A == root) {            root = B;        }        else {            if (parentOfA.left == A) {                parentOfA.left = B;            }            else {                parentOfA.right = B;            }        }        A.right = B.left; // Make T2 the right subtree of A        B.left = A;        updateHeight((AVLTreeNode)A);        updateHeight((AVLTreeNode)B);    }    /** Balance RL (see Figure 26.5) */    private void balanceRL(TreeNode A, TreeNode parentOfA) {        TreeNode B = A.right; // A is right-heavy        TreeNode C = B.left; // B is left-heavy        if (A == root) {            root = C;        }        else {            if (parentOfA.left == A) {                parentOfA.left = C;            }            else {                parentOfA.right = C;            }        }        A.right = C.left; // Make T2 the right subtree of A        B.left = C.right; // Make T3 the left subtree of B        C.left = A;        C.right = B;        // Adjust heights        updateHeight((AVLTreeNode)A);        updateHeight((AVLTreeNode)B);        updateHeight((AVLTreeNode)C);    }    @Override /** Delete an element from the AVL tree.    * Return true if the element is deleted successfully    * Return false if the element is not in the tree */    public boolean delete(E element) {        if (root == null)            return false; // Element is not in the tree        // Locate the node to be deleted and also locate its parent node        TreeNode parent = null;        TreeNode current = root;        while (current != null) {            if (element.compareTo(current.element)  0) {                parent = current;                current = current.right;            }            else                break; // Element is in the tree pointed by current        }        if (current == null)            return false; // Element is not in the tree        // Case 1: current has no left children (See Figure 25.10)        if (current.left == null) {            // Connect the parent with the right child of the current node            if (parent == null) {                root = current.right;            }            else {                if (element.compareTo(parent.element) < 0)                    parent.left = current.right;                else                    parent.right = current.right;                // Balance the tree if necessary                balancePath(parent.element);            }        }        else {            // Case 2: The current node has a left child            // Locate the rightmost node in the left subtree of            // the current node and also its parent            TreeNode parentOfRightMost = current;            TreeNode rightMost = current.left;            while (rightMost.right != null) {                parentOfRightMost = rightMost;                rightMost = rightMost.right; // Keep going to the right            }            // Replace the element in current by the element in rightMost            current.element = rightMost.element;            // Eliminate rightmost node            if (parentOfRightMost.right == rightMost)                parentOfRightMost.right = rightMost.left;            else                // Special case: parentOfRightMost is current                parentOfRightMost.left = rightMost.left;            // Balance the tree if necessary            balancePath(parentOfRightMost.element);        }        size--;        return true; // Element inserted    }    /** AVLTreeNode is TreeNode plus height */    protected static class AVLTreeNode<E extends Comparable> extends BST.TreeNode {        protected int height = 0; // New data field        public AVLTreeNode(E e) {            super(e);        }    }}

avltree 类扩展了bst。与 bst 类一样,avltree 类有一个无参构造函数,用于构造一个空的 avltree(第 5 行),以及一个从元素数组创建初始 avltree 的构造函数(第 8-10 行) .

bst类中定义的createnewnode()方法创建一个treenode。重写此方法以返回 avltreenode(第 13-15 行)。

分类插件jquery.sort.js 分类插件jquery.sort.js

分类插件jquery.sort.js

分类插件jquery.sort.js 41 查看详情 分类插件jquery.sort.js

avltree中的insert方法在第18-27行被覆盖。该方法首先调用bst中的insert方法,然后调用balancepath(e)(第23行)来确保树是平衡的。

balancepath方法首先获取从包含元素e的节点到根节点的路径上的节点(第45行)。对于路径中的每个节点,更新其高度(第 48 行),检查其平衡系数(第 51 行),并在必要时执行适当的旋转(第 51-67 行)。

第 82-178 行定义了四种执行旋转的方法。每个方法都使用两个

treenode 参数(aparentofa)进行调用,以在节点 a 处执行适当的旋转。帖子中的附图说明了如何执行每次旋转。旋转后,节点abc的高度更新(第98、125、148、175行)。

avltree中的delete方法在第183-248行被重写。该方法与bst类中实现的方法相同,只是在两种情况下需要在删除后重新平衡节点(第218、243行)。

以上就是AVLTree 类的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/509547.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
vivo Y35自动亮度太高怎么改 vivo Y35显示模式讲解
上一篇 2025年11月9日 00:01:57
JavaScript和WebSocket:打造高效的实时图像处理系统
下一篇 2025年11月9日 00:02:02

相关推荐

  • 掌握JavaScript中let关键字的变量作用域与声明实践

    本文深入探讨了javascript中`let`关键字的作用域规则和变量声明的最佳实践。通过具体代码示例,详细解释了在块级作用域内重复使用`let`声明同名变量的常见误区及其导致的意外行为。文章强调了`let`变量应只声明一次,后续操作仅进行赋值,以避免创建新的局部变量并正确管理程序状态。 理解let…

    2025年12月23日
    100
  • Flask模板中迭代SQLAlchemy查询结果:解决因空白字符导致的显示问题

    本教程探讨在flask模板中迭代处理sqlalchemy查询结果时,如何解决因字符串中隐藏的空白字符导致的显示不完整问题。当通过`split(‘,’)`方法分割标签字符串时,未去除的空白字符可能导致数据库查询匹配失败。文章将详细介绍如何利用python的`strip()`方法…

    2025年12月23日
    000
  • 电脑怎么运行HTML5_电脑运行HTML5方法【教程】

    首先使用现代%ignore_a_1%如Chrome或Firefox并确保更新至最新版本,接着通过右键菜单用浏览器直接打开本地.html文件;然后检查浏览器设置中JavaScript及音视频权限是否启用,避免功能受限;若页面异常,按F12使用开发者工具的Console和Elements面板排查脚本错误…

    2025年12月23日
    000
  • 深入理解 Bootstrap 3 列等高:Flexbox 解决方案

    本教程旨在解决 %ignore_a_1% 3 中列高不一致的常见布局问题。我们将利用 css flexbox 属性,通过定义自定义类并巧妙地应用于 html 结构,实现不同内容量列的等高显示。此方法无需 javascript,提供了一种纯 css 的解决方案,确保视觉对齐和布局美观。 Bootstr…

    2025年12月23日
    100
  • 笔记本电脑上怎么运行html文件_笔记本运行html文件方法【指南】

    可通过浏览器或代码编辑器直接运行本地HTML文件。一、右键HTML文件选择“打开方式”并选浏览器即可加载页面;二、将文件拖拽至已打开的浏览器窗口中自动渲染;三、使用VS Code等编辑器安装Live Server插件实现自动刷新预览;四、双击文件通过默认关联程序(如浏览器)打开,确保扩展名为.htm…

    2025年12月23日
    000
  • 在VS Code中正确引用外部CSS样式表的指南

    中的路径是否与CSS文件的实际位置匹配。特别是当HTML和CSS不在同一目录时,相对路径容易出错。建议使用VS Code的自动补全功能,它通常能帮助您选择正确的路径。 文件扩展名是否正确?确保HTML文件以 .html 结尾,CSS文件以 .css 结尾。 是否保存了所有文件?在VS Code中,文…

    2025年12月23日
    000
  • 从Google Docs恢复原始HTML文件:利用版本历史功能

    本文详细介绍了当html文件上传至google drive后被自动转换为google docs格式,导致无法直接下载原始html内容的问题。针对此情况,教程提供了一种有效的解决方案:通过google docs的版本历史功能,用户可以轻松定位并下载最初上传的html文件,从而恢复原始数据。 问题背景与…

    2025年12月23日
    000
  • 如何高效管理与监听JavaScript中并行异步操作的完成状态

    本教程将深入探讨在javascript中如何优雅地处理和监听多个并行异步操作(如`fetch`请求)的整体完成状态。我们将分析传统`foreach`循环在异步场景下的局限性,并详细介绍如何利用`promise.all`结合`async/await`语法,确保所有异步任务执行完毕后,再执行后续逻辑,从…

    2025年12月23日
    000
  • HTML/CSS实现文本即时显示与缓慢淡出效果的教程

    本教程详细介绍了如何利用css的transition属性结合:hover和:not(:hover)伪类,实现文本在鼠标悬停时即时(或极快)显示,并在鼠标移开时缓慢淡出的动态效果。文章通过具体代码示例,解释了如何精确控制过渡时长和样式变化,以创建流畅且用户友好的交互体验。 在现代网页设计中,为提升用户…

    2025年12月23日
    000
  • jQuery Mobile 导航栏的响应式控制与动态显示策略

    本文旨在解决 jQuery Mobile 应用中底部导航栏元素的动态显示问题。针对直接使用 `hide()`/`show()` 效果不佳的情况,我们将深入探讨如何利用 JavaScript 的 `Window.matchMedia` API 实现基于屏幕尺寸等条件的响应式控制。同时,文章还将介绍 C…

    2025年12月23日
    000
  • ai做html怎么运行_AI生成html运行步骤【教程】

    答案是使用AI生成HTML代码后,将其保存为.html文件并用浏览器打开即可运行。具体步骤为:1. 在AI工具中输入需求生成HTML代码;2. 将代码复制到文本编辑器并另存为index.html,编码选UTF-8,类型选“所有文件”;3. 双击该文件用浏览器打开,若无法正常显示需检查文件后缀、编码及…

    2025年12月23日
    000
  • 基于jQuery Simple Lightbox实现数据库图片弹窗展示教程

    本教程详细介绍了如何利用jQuery Simple Lightbox插件,将从数据库中获取的图片以优雅的弹窗形式展示给用户。通过引入必要的CSS和JavaScript库,并对HTML结构进行简单调整,您可以轻松实现点击图片后在当前页面中央弹出大图的效果,提升用户体验,避免页面跳转。 在现代网页应用中…

    2025年12月23日
    000
  • CSS后代选择器与子选择器深度解析:理解元素层级关系与精确选择

    CSS后代选择器与子选择器深度解析:理解元素层级关系与精确选择CSS后代选择器与子选择器深度解析:理解元素层级关系与精确选择CSS后代选择器与子选择器深度解析:理解元素层级关系与精确选择CSS后代选择器与子选择器深度解析:理解元素层级关系与精确选择

    本文深入探讨css中的后代选择器(空格)与子选择器(>),阐明它们在定位html元素时的核心差异。通过形象的比喻和详细的代码示例,教程将帮助读者理解元素间的层级关系,并学会如何构建精确且高效的css选择器,以实现对页面元素的精准样式控制。 CSS选择器基础:理解元素层级关系 在网页开发中,CS…

    2025年12月23日 用户投稿
    000
  • 掌握CSS按钮悬停动画:使用Transition属性实现流畅交互

    本教程将详细介绍如何利用css的`transition`属性为html按钮实现平滑的悬停动画,无需复杂的javascript。文章将涵盖`transition`的基本用法、`:hover`伪类的应用,并通过代码示例演示如何改变背景、颜色和缩放效果,以提升用户界面的交互体验。 提升按钮交互体验:理解C…

    2025年12月23日
    000
  • 怎么运行html瑞香t_运行html瑞香t方法【教程】

    运行HTML文件只需用浏览器打开,无需“瑞香t”等工具;可通过双击、右键选择浏览器、拖拽到浏览器或使用VS Code的Live Server插件实时预览,配合编辑器与开发者工具提升开发效率。 运行HTML文件其实很简单,不需要复杂的工具或环境。所谓“瑞香t”可能是输入错误或误解,这里为你详细介绍如何…

    2025年12月23日
    000
  • 网页多图片上传与预览最佳实践:避免ID重复,巧用类选择器

    本教程旨在解决网页中多个独立图片上传与预览功能冲突的问题。核心在于强调html id 属性的唯一性原则,并演示如何利用 class 属性和javascript的事件委托或遍历机制,为页面上每个独立的图片上传组件绑定正确的事件监听器,确保每个上传操作只影响其对应的图片显示区域,从而实现多图片上传功能的…

    2025年12月23日
    000
  • 服务器怎么运行html_服务器运行html文件步骤【指南】

    首先确认服务器环境并安装Web服务软件,如Apache或Nginx;将HTML文件上传至默认根目录(如/var/www/html/),设置正确权限与文件名;配置服务器的DirectoryIndex、访问权限及MIME类型;通过浏览器输入IP或域名访问页面;最后检查防火墙、端口、日志和本地代码以排除常…

    2025年12月23日
    000
  • Flexbox布局中多元素垂直与水平对齐的实践指南

    Flexbox布局中多元素垂直与水平对齐的实践指南Flexbox布局中多元素垂直与水平对齐的实践指南Flexbox布局中多元素垂直与水平对齐的实践指南Flexbox布局中多元素垂直与水平对齐的实践指南

    本教程旨在解决使用flexbox对多个独立元素进行垂直和水平对齐的常见挑战。文章通过一个实际案例,详细阐述了如何通过合理地包裹相关内容、正确设置flex容器(`display: flex`)以及精准运用`justify-content`和`align-items`等flexbox属性,来实现预期布局…

    2025年12月23日 用户投稿
    000
  • 登录界面图标颜色优化:如何在不影响背景色的情况下改变PNG背景图颜色

    本文探讨了在登录界面中,如何在不改变输入框背景色的前提下,将png图标的颜色从黑色转换为白色。针对css滤镜的局限性,文章推荐使用专业的图像编辑工具直接修改png图片,以实现精确且兼容性强的效果,并提供了实际操作的建议和注意事项。 在现代Web应用开发中,尤其是在登录或注册界面,为输入框添加带有图标…

    2025年12月23日
    000
  • html前端怎么运行_运行html前端代码步骤【指南】

    运行HTML前端代码只需电脑和浏览器。1. 直接双击打开.html文件最简单,适合初学;2. 用VS Code等编辑器配合Live Server实现保存自动刷新;3. 需要服务器时可用Node.js或Python启动本地服务;4. 在线工具如CodePen、JSFiddle、StackBlitz免安…

    2025年12月23日
    000

发表回复

登录后才能评论
关注微信