堆排序:利用堆的特性进行排序,先将数组转换为堆对象(最大堆或最小堆),以最大堆为例,每次heapify之后,取出堆顶(索引为0)的元素与最后一个元素交换。以后每次做同样的事情,只是堆的长度每次-1,直到1为止(最后一个元素不需要调整)。
堆排序流程
将数组调整为堆模型
我们以最大堆为例,传入一个无序的数组。先将其调整为堆最大堆模型,也就是最大值在第一个位置(树的根节点)。
定义数组存储待排序内容
public class HeapSort {private int[] elements; //堆的数组public HeapSort(int[] elements) {this.elements = elements;}}
定义heapify方法对数组调整大堆结构
public void heapify(int curr,int size) {//1. 设置当前节点为最大节点int largest = curr;//2. 计算当前节点的左子节点,和右子节点int left = 2 * curr + 1;int right = 2 * curr + 2;// 3.1比较左子节点if (left < size && elements[left] > elements[largest]) {largest = left;}if (right < size && elements[right] > elements[largest]) {largest = right;}//交换largsetif (largest != curr) {int tmp = elements[largest];elements[largest] = elements[curr];elements[curr] = tmp;heapify(largest,size);}}
对数组使用堆排序
所谓堆排序,是我们将每次调整后的最大值(即堆的顶点即第一个元素)和最后一个元素进行调换,然后对除最后一个元素的所有元素继续按大堆进行调整。
public void sort() {int len = elements.length;//数组长度每轮减一,将第一个元素移到从后向前的位置。while (len>1) {for(int i = len/2-1;i>=0;i--){heapify(i, len);}swap(0,--len);}}/*** 数组中的元素交换的方法*/ public void swap(int i,int j){int t = elements[i];elements[i] = elements[j];elements[j] = t;}/*** 打印数组元素*/
public void print() {System.out.println(Arrays.toString(this.elements));
}
测试排序
public static void main(String[] args) {int[] a = {3, 9, 2, 1, 4, 5};System.out.println("init: " + Arrays.toString(a));HeapSort hs = new HeapSort(a);hs.sort();hs.print();}