堆排序基本介绍
1) 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序(不能保证相同的两个数的位置和原来一样)。
2) 堆是具有以下性质的完全二叉树(叶子节点只出现在最后一层或倒数第二层):每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意 : 没有要求结点的左孩子的值和右孩子的值的大小关系。
3) 每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆 。
4) 大顶堆举例说明
6) 一般升序采用大顶堆,降序采用小顶堆
堆排序基本思想:
1) 将待排序序列构造成一个大顶堆
2) 此时,整个序列的最大值就是堆顶的根节点。
3) 将其与末尾元素进行交换,此时末尾就为最大值。
4) 然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
代码实现:
import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class HeapSort { public static void main(String[] args) { //要求将数组升序排列 int[] arr={3,7,5,2,6,4,1,9,8}; System.out.println("排序前"); String date1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); System.out.println(date1); //堆排序 heapSort(arr); System.out.println("排序后"); String date2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); System.out.println(date2); // System.out.println(Arrays.toString(arr)); } //编写一个升序排列的方法 public static void heapSort(int[] arr){ int temp=0; //将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆 for (int i= arr.length/2-1;i>=0;i--){ adjustHeap(arr,i, arr.length); } //将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端; //重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。 for (int j= arr.length-1;j>0;j--){ //交换 temp=arr[j]; arr[j]=arr[0]; arr[0]=temp; adjustHeap(arr,0,j); } } //将一个数组(二叉树),调整成为一个大顶堆 /** * * @param arr 待调整的数组 * @param i 表示非叶子节点在数组中索引 * @param length 表示对多少个元素继续调整,length是在逐渐减少 */ public static void adjustHeap(int arr[],int i,int length){ int temp=arr[i]; for (int k = i*2+1; k < length; k=k* 2+1) { if (k+1<length&&arr[k]<arr[k+1]){ //说明左子节点的值小于右子节点的值 k++;//k指向右子结点 } if (arr[k]>temp){//如果子结点大于父结点 arr[i]=arr[k];//把较大的值赋给当前结点 arr[k]=temp;//将temp值放到调整后的位置 i=k;//!!!i指向k,继续循环比较 }else { break; } } } }