使用一个不可变对象作为key,红黑树怎么比较大小?
答:Java 中的红黑树是通过左旋、右旋的方式来维护树的平衡性,而左旋、右旋又依赖于节点大小的比较。对于使用不可变对象作为key实际上是可以的,因为比较key的大小本身不依赖于key是否可变性,而是依赖于key实现的比较大小的方法。
作为红黑树中的key有如下几个条件
- key必须是对象,不能是基本数据类型(如 int、double等,对应的包装类是可以的);
- 作为key的该对象必须要实现Comparable接口,并重写
compareTo
方法,用于比较对象的顺序。compareTo
方法返回值是一个整数,如果当前对象小于参数对象,应返回负整数;如果当前对象大于参数对象,应返回正整数;如果两个对象相等,应返回0。
使用红黑树实现排序的案例
java
import java.util.Comparator;
import java.util.TreeSet;
class Person implements Comparable<Person> {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Person other) {
// 先按照姓名比较
int nameComparison = this.name.compareTo(other.name);
if (nameComparison != 0) {
return nameComparison;
}
// 若姓名相同,则按照年龄比较
return Integer.compare(this.age, other.age);
}
}
public class RedBlackTreeExample {
public static void main(String[] args) {
// 创建红黑树,并添加元素
TreeSet<Person> treeSet = new TreeSet<>();
treeSet.add(new Person("Alice", 25));
treeSet.add(new Person("Bob", 30));
treeSet.add(new Person("Charlie", 20));
treeSet.add(new Person("Alice", 30));
// 遍历红黑树
for (Person person : treeSet) {
System.out.println(person.getName() + ", " + person.getAge());
}
}
}
知识扩展:
(1)红黑树的插入和查找操作是如何利用键的比较结果来维护树的有序性的?
红黑树通过键的比较结果来维护树的有序性。在插入和查找操作中,红黑树根据键的比较结果来确定节点的位置,以保持树的有序性。
插入操作:
- 从根节点开始,将要插入的节点与当前节点进行键的比较。如果要插入的节点的键小于当前节点的键,则继续在当前节点的左子树中继续比较;如果要插入的节点的键大于当前节点的键,则继续在当前节点的右子树中继续比较。
- 重复上述步骤,直到找到一个空位置,将要插入的节点放入该位置。
- 插入节点后,通过旋转和重新着色操作,确保红黑树的性质得到恢复和维护。这些操作旨在保持红黑树的平衡性和有序性。
查询操作:
- 从根节点开始,将要查找的键与当前节点进行比较。如果要查找的键等于当前节点的键,则返回当前节点。
- 如果要查找的键小于当前节点的键,则继续在当前节点的左子树中继续比较。
- 如果要查找的键大于当前节点的键,则继续在当前节点的右子树中继续比较。
- 重复上述步骤,直到找到等于要查找键的节点或者遍历到叶子节点为止。如果遍历到叶子节点仍未找到匹配的节点,则表示键不存在于红黑树中。