比较器Comparable 及 二叉树的排序算法!!

本文介绍Java中如何使用Arrays.sort()方法对自定义对象数组进行排序,通过实现Comparable接口来定义排序规则,并通过示例代码展示从大到小排序的过程。此外,还解释了比较器的工作原理及其实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前Arrays 类中存在sort() 方法, 此方法可以直接对 对象数组进行排序。

 1.Comparable接口

可以直接使用java.util.Arrays 类进行数组的排序操作,但对象所在的类必须实现Comparable 接口,用于指定排序接口。

Comparable 接口定义如下:

public interface Comparable<T>{

public int compareTo(T o);

}

此方法返回一个int 类型的数据,但是此int 的值只能是以下三种:

1:表示大于 

-1:表示小于

0:表示相等

定义一个学生类,里面有数字,要求按数字由大到小排序

package demo2;

public class Student implements Comparable{
    int a;

	public Student(int a) {
		super();
		this.a = a;
	}

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	public int compareTo(Object o) {
		
		Student t = (Student)o;
		System.out.println("t.a="+t.a);
		System.out.println("this.a="+this.a);
		System.out.println();
		if(t.a>this.a) {
			return 1;
		}else if(t.a < this.a) {
			return -1;
		}else {
		return 0;}
	}

	@Override
	public String toString() {
		return "Student [a=" + a + "]";
	}
    
}
package demo2;


import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;


public class Test {
    public static void main(String[] args) {
		 Set set = new TreeSet();
		 
		 
		 set.add(new Student(6));
		 set.add(new Student(9));
		 set.add(new Student(3));
		 set.add(new Student(4));
		 set.add(new Student(5));
		 set.add(new Student(1));
		 set.add(new Student(8));
		 set.add(new Student(7));
		 set.add(new Student(2));
		 set.add(new Student(10));
		 
		 
		 
		 Iterator i = set.iterator();
		 
          while(i.hasNext()) {
        	  Student s = (Student)i.next();
        	  System.out.println(s);
          }
	}
}

运行结果:

t.a=6
this.a=6

t.a=6
this.a=9

t.a=6
this.a=3

t.a=6
this.a=4

t.a=3
this.a=4

t.a=6
this.a=5

t.a=3
this.a=5

t.a=4
this.a=5

t.a=6
this.a=1

t.a=4
this.a=1

t.a=3
this.a=1

t.a=6
this.a=8

t.a=9
this.a=8

t.a=6
this.a=7

t.a=9
this.a=7

t.a=8
this.a=7

t.a=6
this.a=2

t.a=4
this.a=2

t.a=3
this.a=2

t.a=1
this.a=2

t.a=6
this.a=10

t.a=8
this.a=10

t.a=9
this.a=10

Student [a=10]
Student [a=9]
Student [a=8]
Student [a=7]
Student [a=6]
Student [a=5]
Student [a=4]
Student [a=3]
Student [a=2]
Student [a=1]
2.分析比较器的排序原理

实际上比较器的操作,就是经常听到的二叉树的排序算法。通过二叉树进行排序,之后利用中序遍历的方法把内容依次读取出来。

排序的基本原理,使用第一个元素作为根节点,之后如果后面的内容比根节点要大,则放在左子树,如果内容比根节点的内容要大,则放在右子树。


然后以中序遍历(左根右)输出!


### 比较器的定义与用法 比较器在编程中通常用于定义对象之间的比较规则,尤其是在需要对集合或数组中的元素进行排序时。Java 提供了两种主要的比较器接口:`Comparable` 和 `Comparator`。 #### 1. `Comparable` 接口 `Comparable` 是一种内部比较器,它通过让类自身实现该接口来定义默认的比较规则。当一个类实现了 `Comparable` 接口时,必须重写 `compareTo` 方法以指定如何比较两个对象[^1]。 - **特点**: - 与类紧密耦合,适用于自然排序(如数字升序、字符串字典序)。 - 只能定义一种排序规则。 - **示例代码**: ```java public class Student implements Comparable<Student> { public String name; public int id; public int age; public Student(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } @Override public int compareTo(Student other) { return this.age - other.age; // 按年龄升序排序 } } ``` #### 2. `Comparator` 接口 `Comparator` 是一种外部比较器,允许开发者为同一类定义多种不同的比较规则。通过实现 `Comparator` 接口并重写 `compare` 方法,可以灵活地定义任意数量的排序方式[^2]。 - **特点**: - 灵活性高,适合定义多种排序规则。 - 不改变原有类的结构,便于后期维护和扩展。 - **示例代码**: ```java import java.util.Comparator; public class IdAscendingComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.id - o2.id; // 按 ID 升序排序 } } public class IdShengAgeJiangOrder implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.id != o2.id ? (o1.id - o2.id) : (o2.age - o1.age); // 按 ID 升序,相同 ID 按年龄降序 } } ``` #### 3. 使用 Lambda 表达式简化比较器 从 Java 8 开始,`Comparator` 被标记为函数式接口,可以通过 Lambda 表达式进一步简化其定义[^4]。 - **示例代码**: ```java import java.util.TreeMap; TreeMap<Student, String> treeMap = new TreeMap<>((a, b) -> a.id - b.id); // 使用 Lambda 表达式按 ID 升序排序 ``` #### 4. 在排序算法中的应用 比较器不仅用于集合框架中的排序,还可以在自定义排序算法(如堆排序)中发挥作用。例如,在堆排序中,比较器可用于定义堆的优先级规则[^3]。 - **堆排序中的比较器**: - 堆是一种完全二叉树结构,其节点满足特定的比较规则(如大顶堆或小顶堆)。 - 通过自定义比较器,可以灵活调整堆的结构和排序逻辑。 ```java public class HeapSort { public static void heapify(Student[] arr, int n, int i, Comparator<Student> comparator) { int largest = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left < n && comparator.compare(arr[left], arr[largest]) > 0) { largest = left; } if (right < n && comparator.compare(arr[right], arr[largest]) > 0) { largest = right; } if (largest != i) { Student swap = arr[i]; arr[i] = arr[largest]; arr[largest] = swap; heapify(arr, n, largest, comparator); } } public static void sort(Student[] arr, Comparator<Student> comparator) { int n = arr.length; for (int i = n / 2 - 1; i >= 0; i--) { heapify(arr, n, i, comparator); } for (int i = n - 1; i > 0; i--) { Student temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; heapify(arr, i, 0, comparator); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值