Java中的AVL树旋转

2023-12-21

我想实现Java AVL树并左右旋转树。我不明白这个。

任何人都可以通过查看下面的代码告诉我如何左右旋转树,然后使用 fix up 与这两个函数来平衡 AVL 树?

我希望这里有人可以指导我完成这个任务。

import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;

public class AVLTree<T> extends 
BinarySearchTree<AVLTree.Node<T>, T> implements SSet<T> {

    Random rand;

    public static class Node<T> extends BSTNode<Node<T>,T> {
        int h;  // the height of the node
    }

    public AVLTree() {
        sampleNode = new Node<T>();
        rand = new Random();
        c = new DefaultComparator<T>();
    }

    public int height(Node<T> u) {
        return (u == null) ? 0 : u.h;
    }

    public boolean add(T x) {
        Node<T> u = new Node<T>();
        u.x = x;
        if (super.add(u)) {
            for (Node<T> w = u; w != nil; w = w.parent) {
                // walk back up to the root adjusting heights
                w.h = Math.max(height(w.left), height(w.right)) + 1;
            }
        fixup(u);
        return true;
    }
    return false;
}

public void splice(Node<T> u) {
    Node<T> w = u.parent;
    super.splice(u);
    for (Node<T> z = u; z != nil; z = z.parent)
        z.h = Math.max(height(z.left), height(z.right)) + 1;            
    fixup(w);
}

public void checkHeights(Node<T> u) {
    if (u == nil) return;
    checkHeights(u.left);
    checkHeights(u.right);
    if (height(u) != 1 + Math.max(height(u.left), height(u.right))) 
        throw new RuntimeException("Check heights shows incorrect heights");
    int dif = height(u.left) - height(u.right);
    if (dif < -1 || dif > 1)
        throw new RuntimeException("Check heights found height difference of " + dif);
}

/**
 * TODO: finish writing this method
 * @param u
 */
public void fixup(Node<T> u) {
    while (u != nil) {
        int dif = height(u.left) - height(u.right);
        if (dif > 1) {
            // TODO: add code here to fix AVL condition 
            // on the path from u to the root, if  necessary
        } else if (dif < -1) {
            // TODO: add code here to fix AVL condition
            // on the path from u to the root, if necessary                 
        }
        u = u.parent;
    }
}

public Node rotateLeft() {
    return rotateLeft(u.parent);
}

public void rotateLeft(Node<T> u) {
    // TODO: Recompute height values at u and u.parent
}

public void rotateRight(Node<T> u) {
    // TODO: Recompute height values at u and u.parent
}

public static <T> T find(SortedSet<T> ss, T x) {
    SortedSet<T> ts = ss.tailSet(x);
    if (!ts.isEmpty()) {
        return ts.first(); 
    }
    return null;
}

/**
 * This just does some very basic correctness testing
 * @param args
 */
public static void main(String[] args) {
    AVLTree<Integer> t = new AVLTree<Integer>();
    Random r = new Random(0);
    System.out.print("Running AVL tests...");
    int n = 1000;
    for (int i = 0; i < n; i++) {
        t.add(r.nextInt(2*n));
        t.checkHeights(t.r);
    }
    for (int i = 0; i < n; i++) {
        t.remove(r.nextInt(2*n));
        t.checkHeights(t.r);
    }
    System.out.println("done");

    t.clear();
    System.out.print("Running correctness tests...");
    n = 100000;
    SortedSet<Integer> ss = new TreeSet<Integer>();
    Random rand = new Random();
    for (int i = 0; i < n; i++) {
        Integer x = rand.nextInt(2*n);
        boolean b1 = t.add(x);
        boolean b2 = ss.add(x);
        if (b1 != b2) {
            throw new RuntimeException("Adding " + x + " gives " + b2 
                    + " in SortedSet and " + b1 + " in AVL Tree");
        }
    }
    for (int i = 0; i < n; i++) {
        Integer x = rand.nextInt(2*n);
        Integer x1 = t.find(x);
        Integer x2 = find(ss, x);
        if (x1 != x2) {
            throw new RuntimeException("Searching " + x + " gives " + x2 
                    + " in SortedSet and " + x1 + " in AVL Tree");
        }
        ss.headSet(x);
    }
    for (int i = 0; i < n; i++) {
        Integer x = rand.nextInt(2*n);
        boolean b1 = t.remove(x);
        boolean b2 = ss.remove(x);
        if (b1 != b2) {
            throw new RuntimeException("Error (2): Removing " + x + " gives " + b2 
                    + " in SortedSet and " + b1 + " in AVL Tree");
        }
    }
    for (int i = 0; i < n; i++) {
        Integer x = rand.nextInt(2*n);
        Integer x1 = t.find(x);
        Integer x2 = find(ss, x);
        if (x1 != x2) {
            throw new RuntimeException("Error (3): Searching " + x + " gives " + x2 
                    + " in SortedSet and " + x1 + " in AVL Tree");
        }
        ss.headSet(x);
    }
    System.out.println("done");
 }
}

完整的AVL树实现:

public class AVLTree<T> {

    private AVLNode<T> root;

    private static class AVLNode<T> {

        private T t;
        private int height;
        private AVLNode<T> left;
        private AVLNode<T> right;

        private AVLNode(T t) {
            this.t = t;
            height = 1;
        }
    }

    public void insert(T value) {
        root = insert(root, value);
    }

    private AVLNode<T> insert(AVLNode<T> n, T v) {
        if (n == null) {
            n = new AVLNode<T>(v);
            return n;
        } else {
            int k = ((Comparable) n.t).compareTo(v);
            if (k > 0) {
                n.left = insert(n.left, v);
            } else {
                n.right = insert(n.right, v);
            }
            n.height = Math.max(height(n.left), height(n.right)) + 1;
            int heightDiff = heightDiff(n);
            if (heightDiff < -1) {
                if (heightDiff(n.right) > 0) {
                    n.right = rightRotate(n.right);
                    return leftRotate(n);
                } else {
                    return leftRotate(n);
                }
            } else if (heightDiff > 1) {
                if (heightDiff(n.left) < 0) {
                    n.left = leftRotate(n.left);
                    return rightRotate(n);
                } else {
                    return rightRotate(n);
                }
            } else;

        }
        return n;
    }

    private AVLNode<T> leftRotate(AVLNode<T> n) {
        AVLNode<T> r = n.right;
        n.right = r.left;
        r.left = n;
        n.height = Math.max(height(n.left), height(n.right)) + 1;
        r.height = Math.max(height(r.left), height(r.right)) + 1;
        return r;
    }

    private AVLNode<T> rightRotate(AVLNode<T> n) {
        AVLNode<T> r = n.left;
        n.left = r.right;
        r.right = n;
        n.height = Math.max(height(n.left), height(n.right)) + 1;
        r.height = Math.max(height(r.left), height(r.right)) + 1;
        return r;
    }

    private int heightDiff(AVLNode<T> a) {
        if (a == null) {
            return 0;
        }
        return height(a.left) - height(a.right);
    }

    private int height(AVLNode<T> a) {
        if (a == null) {
            return 0;
        }
        return a.height;
    }


}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中的AVL树旋转 的相关文章

随机推荐

  • Azure 数据传输身份列种子跃升 10,000

    通过sql脚本插入数据后 那有 SET IDENTITY INSERT dbo table ON SET IDENTITY INSERT dbo table OFF 身份种子增加10000 我尝试过运行重新种子 dbcc CHECKIDEN
  • 如何计算两个值以任意顺序出现在两列中的次数

    可以说 我们有这张表 COL1 COL2 A B B A C D 我也想数一下次数letter1 letter2 or letter2 letter1出现在两列中 我想要结果 COL1 COL2 COL3 A B 2 C D 1
  • RDFlib“磁盘上”存储

    经过 2 天的研究 我 一个新手 仍然无法弄清楚 RDFFlib 3 1 0 中可用的 磁盘 存储 如果您有一个有效的示例 那就很高兴看到 对于我的应用程序 我更喜欢 SQLite 我不需要访问在线 RDF 商店 我想在 RDF 中存储有关
  • Apollo 服务器解析大数据时性能缓慢

    在解析大数据时 我注意到从解析器将结果返回给客户端的那一刻起 性能非常慢 我假设apollo server迭代我的结果并检查类型 无论哪种方式 操作都花费太长时间 在我的产品中 我必须一次性返回大量数据 因为它被一次性用于在 UI 中绘制图
  • 小行星类型游戏中的正确移动

    目前我有某种小行星游戏 可以在这里看到 http www youtube com watch v rQV6H9kWkFE http www youtube com watch v rQV6H9kWkFE 但是当用户在船舶仍在移动的情况下按W
  • Spark RDD 通过键查找

    我有一个从 HBase 转换而来的 RDD val hbaseRDD RDD String Array String 其中 tuple 1 是行键 数组是HBase中的值 4929101 ACTIVE 4929101 2015 05 20
  • 构建 dist 文件夹并将其发布到 github 页面

    我使用 Vue CLI 使用 Vue js 和 Vuetify 创建了一个项目 我想使用 Github Pages 托管此应用程序 所以我从这里拿了一份指南 https help github com en articles configu
  • 为什么 webpack 配置必须使用 path.resolve 和 path.join

    在 webpack 配置中常见的是 当我们需要设置路径时 path resolve or path join经常使用 我只是想弄清楚why我们必须使用它们而不是普通的字符串路径 例如 dist 我部分理解也许出于某种目的 它们用于返回绝对路
  • 使用 CAShapeLayer 对象用 Bezierpath 绘制一条线

    我正在制作一个图像编辑器 它可以创建不同形状的对象 如圆形 三角形和正方形 也可以更新或删除 所以我用过CAShapeLayer用于创建形状对象 现在我还想在图像上画一条线 它也可以更新或删除 所以我使用了 bezierpath 和CASh
  • 奇怪的行为-选择行触摸没有响应 UITableViewCell

    我有一个非常奇怪的问题 我不知道这对细胞的正常行为是否很尴尬 似乎是这样 因此我将其交给可以回答的人 如果有任何愚蠢的事情 请道歉在问这个问题时 通常 当我们触摸表视图单元格时 会发生什么情况是它导航到视图控制器 编码的控制器 现在奇怪的是
  • Perl 的 rand 参数可以有多大?

    rand n 返回一个介于0 and n Will rand对于我的平台上达到整数限制的所有参数 就 随机性 而言 是否按预期工作 这将取决于你的randbits http www perl com doc FMTEYEWTK random
  • 构造函数什么时候抛出异常是正确的?

    构造函数什么时候抛出异常是正确的 或者就 Objective C 而言 初始化器什么时候返回 nil 是正确的 在我看来 如果对象不完整 构造函数应该失败 从而拒绝创建对象 即 构造函数应该与其调用者签订合同 以提供一个功能性和工作对象 可
  • VBA Round 函数与 Worksheet Round 函数

    我尝试将此Excel函数更改为VBA代码 Excel ROUND value sigfig 1 INT LOG10 ABS value VBA Public Function sigfig val As Double sigf As Int
  • 展平集合

    说我有一个Map
  • build.sbt 定义模块之间的项目依赖关系

    我在 PlayFramework 中有项目 它有一个主要项目 没有任何代码 逻辑 它有几个子模块 main admin common shop 模块 管理和商店将基于通用模块 例如 用户 角色 权限等类 所以我必须这样配置它 lazy va
  • 无法形成对 NSTextView 类实例的弱引用

    仅使用 Swift 这是我在 AppDelegate swift 中的代码 import Cocoa class AppDelegate NSObject NSApplicationDelegate IBOutlet var window
  • WPF 中的 DataTemplate 和 DataContext 有什么区别?

    我可以通过以下方式设置视图模型和视图之间的关系DataContext syntax
  • SwiftUI 点击手势选择错误的项目

    所以我正在尝试创建一个自定义图像选择器 类似于 Instagram 但更基本 这就是我使用它创建屏幕的方法 struct NewPostScreen View StateObject var manager SelectNewPostScr
  • 如何在 ion-checkbox 中使用 ngModel?

    我正在尝试与 ngModel 一起使用 但 ngModel 在那里不起作用 我的代码
  • Java中的AVL树旋转

    我想实现Java AVL树并左右旋转树 我不明白这个 任何人都可以通过查看下面的代码告诉我如何左右旋转树 然后使用 fix up 与这两个函数来平衡 AVL 树 我希望这里有人可以指导我完成这个任务 import java util Ran