实现原理:
-
建堆(Heapify):将待排序的数组构建成一个大顶堆(对于升序排序)或小顶堆(对于降序排序)。大顶堆是满足以下性质的完全二叉树:每个节点的值都大于或等于其子节点的值。
-
排序:将堆的根节点(最大值,对于升序排序)与最后一个节点交换,然后将堆的大小减一。由于已经将最大值放到了它最终应该在的位置,接下来需要重新调整堆,以保持堆的性质。这个过程称为“下沉”(Sift Down)或“筛选”(Filter Down)。
-
重复:重复上述过程,直到堆的大小变为1。
package 八大排序; import java.util.Arrays; //堆排序 public class HeapSort { public static void main(String[] args) { int[] arr = {1,4,6,3,2,56,3,-12,-33,76,100}; //第一大步,构建大顶堆 大顶堆:父节点的值大于等于子节点的值 for(int i = arr.length-1;i>=0;i--){ adjust(arr,i,arr.length); } //第二大步,将堆顶和堆底的值进行交换,然后除了堆底的值继续进行大顶堆构建 for(int i=arr.length-1;i>=0;i--){ int temp = arr[i]; arr[i] = arr[0]; arr[0] = temp; adjust(arr,0,i); } System.out.println(Arrays.toString(arr)); } //维护 public static void adjust(int[] arr,int parent,int length){ int child = 2 * parent + 1; while (child<length){ //如果有左孩子的话定义右孩子 int rchild = child + 1; if (rchild<length&&arr[rchild]>arr[child]){//如果有右孩子并且右孩子比左孩子大 child++;//指向右孩子 } //parent和child所指向的节点进行比较 if(arr[parent]<arr[child]){ //父子节点进行交换 int temp = arr[parent]; arr[parent] = arr[child]; arr[child] = temp; //parent向下指,child指向其左右孩子中的最大值 parent = child; child = child * 2 + 1; }else break; } } }