1、堆排序
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。
2、堆
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:
同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子
该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
3、堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
直接上代码:
//方法入口 public static int[] heapSort(int[] arr) { //构建大顶堆 for (int i = arr.length / 2 - 1; i >= 0; i--) { //具体实现,整个构建大顶堆的过程是从下到上,从左到右 adjustHeap(arr, i, arr.length); } for (int k = arr.length - 1; k > 0; k--) { swap(arr, 0, k); adjustHeap(arr, 0, k); } return arr; } private static void adjustHeap(int[] arr, int swapIndex, int length) { int temp = arr[swapIndex]; //置换节点与它的两个子节点组成一个小三角,比较将最大的值,换到顶点 for (int j = 2 * swapIndex + 1; j < length; j = 2 * j + 1) { // j+1<length if (j + 1 < length && arr[j] < arr[j + 1]) { j++; } if (temp < arr[j]) { arr[swapIndex] = arr[j]; swapIndex = j; } else { break; } } arr[swapIndex] = temp; } private static void swap(int[] arr, int i, int k) { int temp = arr[k]; arr[k] = arr[i]; arr[i] = temp; }
版本二
package algorithm.sorts; import java.util.Arrays; public class HeapSortV2 { public static void main(String[] args) { int[] arr = {1, 9, 2, 5, 23, 88, 4, 1231}; heapSort(arr, arr.length); System.out.println(Arrays.toString(arr)); } private static void heapSort(int[] arr, int length) { //构建大顶堆,此时最大的数在顶点 buildHeap(arr, length); for (int i = length - 1; i >= 0; i--) { //把顶点与最后一位进行交换 swap(arr, 0, i); //把剩下的数再构建成大顶堆 heapify(arr, 0, i); } } private static void buildHeap(int[] arr, int length) { int startNode = length / 2 - 1; for (int i = startNode; i >= 0; i--) { heapify(arr, i, length); } } private static void heapify(int[] arr, int i, int length) { if (i >= length) { return; } int max = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left < length && arr[left] > arr[max]) { max = left; } if (right < length && arr[right] > arr[max]) { max = right; } if (max != i) { swap(arr, i, max); heapify(arr, max, length); } } private static void swap(int[] arr, int i, int max) { int temp = arr[i]; arr[i] = arr[max]; arr[max] = temp; } }
来源:oschina
链接:https://my.oschina.net/u/4055223/blog/4307541