最近需求用到堆排序,写了个堆排工具类,排序对象需要实现Comparable类,重写compareTo方法即可。
public class HeapSort<T extends Comparable<T>> {
private static final int index = 2;
/***
* 堆排序
* @param heap heap
* @param isAsc isAsc
*/
public void heapSort(List<T> heap, boolean isAsc) {
// 构建堆
for (int i = (heap.size() >> 1) - 1; i >= 0; i--) {
if (isAsc) {
adjustBigTopHeap(heap, i, heap.size());
} else {
adjustSmallTopHeap(heap, i, heap.size());
}
}
// 调整堆
for (int i = heap.size() - 1; i > 0; i--) {
Collections.swap(heap, 0, i);
if (isAsc) {
adjustBigTopHeap(heap, 0, i);
} else {
adjustSmallTopHeap(heap, 0, i);
}
}
}
// 降序构造小顶堆(堆顶元素小于左右孩子--升序),在堆顶元素与末尾元素交换过程中形成降序
private void adjustSmallTopHeap(List<T> heap, int start, int length) {
// 先取出当前元素start
T objectTemp = heap.get(start);
// 从start结点的左子结点开始,也就是2*start+1处开始
for (int k = index * start + 1; k < length; k = index * k + 1) {
// 如果左子结点小于右子结点,k指向右子结点
if (k + 1 < length && heap.get(k).compareTo(heap.get(k + 1)) > 0) {
k++;
}
// 如果最小的子节点大于父节点,将子节点值赋给父节点(不用进行交换)
if (heap.get(k).compareTo(objectTemp) < 0) {
T object = heap.get(k);
heap.remove(start);
heap.add(start, object);
start = k;
} else {
break;
}
}
// 将temp值放到最终的位置
heap.remove(start);
heap.add(start, objectTemp);
}
// 升序构造大顶堆(堆顶元素大于左右孩子--降序),在堆顶元素与末尾元素交换过程中形成升序
private void adjustBigTopHeap(List<T> heap, int start, int length) {
// 先取出当前元素start
T objectTemp = heap.get(start);
// 从start结点的左子结点开始,也就是2*start+1处开始
for (int k = index * start + 1; k < length; k = index * k + 1) {
// 如果左子结点大于右子结点,k指向右子结点
if (k + 1 < length && heap.get(k).compareTo(heap.get(k + 1)) < 0) {
k++;
}
// 如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
if (heap.get(k).compareTo(objectTemp) > 0) {
T object = heap.get(k);
heap.remove(start);
heap.add(start, object);
start = k;
} else {
break;
}
}
// 将temp值放到最终的位置
heap.remove(start);
heap.add(start, objectTemp);
}
}
测试类:
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
Student s1 = new Student("tom", 19);
Student s2 = new Student("jack", 16);
Student s3 = new Student("suse", 20);
Student s4 = new Student("lili", 18);
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
HeapSort<Student> heap = new HeapSort<>();
heap.heapSort(list, false);
System.out.println(JSONObject.toJSONString(list));
}
}
@Setter
@Getter
class Student implements Comparable<Student> {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
return Integer.compare(this.age, o.age);
}
}
测试结果:降序
[{"age":20,"name":"suse"},{"age":19,"name":"tom"},{"age":18,"name":"lili"},{"age":16,"name":"jack"}]