Java实现堆排序

小咪咪 2022-02-26 06:24 305阅读 0赞

Java实现 堆排序 Heap Sort

堆排序快速排序归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。

堆的定义

  n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆。

  情形1:ki <= k2i 且ki <= k2i+1 (最小化堆小顶堆

  情形2:ki >= k2i 且ki >= k2i+1 (最****化堆大顶堆

  其中i=1,2,…,n/2向下取整;

若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。

  由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。

堆的存储

  一般用数组来表示堆,若根结点存在序号0处, i结点的父结点下标就为(i-1)/2。i结点的左右子结点下标分别为2*i+1和2*i+2。

  1. ![aHR0cDovL2hpLmNzZG4ubmV0L2F0dGFjaG1lbnQvMjAxMTA4LzIyLzBfMTMxNDAxNDcwNmdacW4uZ2lm][]

堆排序的实现

  实现堆排序需要解决两个问题:

    1.如何由一个无序序列建成一个堆?

    2.如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?

  先考虑第二个问题,一般在输出堆顶元素之后,视为将这个元素排除,然后用表中最后一个元素填补它的位置,自上向下进行调整:首先将堆顶元素和它的左右子树的根结点进行比较,把最小的元素交换到堆顶;然后顺着被破坏的路径一路调整下去,直至叶子结点,就得到新的堆。

  我们称这个自堆顶至叶子的调整过程为“筛选”。

  从无序序列建立堆的过程就是一个反复“筛选”的过程。

  1. public class HeapSort {
  2. int[] arr;
  3. public static void main(String[] args) {
  4. HeapSort heapSor = new HeapSort();
  5. int[] arr = new int[100]; //0下标放的是数组长度,
  6. for(int i=arr.length-1;i>=0;i--){
  7. Random r = new Random();
  8. arr[i] = i*r.nextInt(10000);
  9. }
  10. Date date1 = new Date();
  11. System.out.println("----------开始----------"+date1);
  12. heapSor.arr = arr;
  13. heapSor.heapSort(arr);
  14. Date date2 = new Date();
  15. System.out.println("----------结束----------"+date2);
  16. for(int i=0;i<arr.length;i++){
  17. System.out.println(arr[i]);
  18. }
  19. System.out.println("用时:"+(date2.getTime()-date1.getTime()));
  20. }
  21. void heapAdjust(int[] arr,int s,int m){
  22. //已知arr[s...m]中记录的关键字除arr[s]之外均满足堆的定义,本函数调整arr[s]的关键字,使arr[s...m]成为一个最大堆
  23. int rc = arr[s]; //s是最后一个非叶子节点
  24. for(int j=2*s;j <= m;j = s*2){
  25. if(j<m && arr[j]<arr[j+1])
  26. j++; //j为key较大的下标
  27. if(rc >= arr[j]) break;
  28. arr[s] = arr[j]; //上移到父节点
  29. s=j;
  30. }
  31. arr[s]=rc; //要放入的位置
  32. }
  33. void heapSort(int[] arr){
  34. //对数组进行建堆操作,就是从最后一个非叶结点进行筛选的过程
  35. for(int i=(arr.length-1)/2;i > 0;i--){//因为0没有使用,所以length-1
  36. heapAdjust(arr,i,arr.length-1);
  37. }
  38. System.out.println("........建堆完成.............");
  39. outputArr(1);
  40. for(int i=arr.length-1; i>1; i--){
  41. int temp = arr[1];
  42. arr[1] = arr[i];
  43. arr[i] = temp;
  44. heapAdjust(arr,1,i-1);
  45. }
  46. }
  47. void outputArr(int i){
  48. if(i <= arr[0]){
  49. System.out.println(arr[i]);
  50. outputArr(i*2); //左
  51. outputArr(i*2+1); //右
  52. }
  53. }
  54. }

发表评论

表情:
评论列表 (有 0 条评论,305人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java实现排序

    一、堆排序基本介绍 1. 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复 杂度均为 O(nlogn),它也是不稳定...

    相关 Java实现排序

    > 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二

    相关 排序java实现

    一、前言 堆是一个数组,它可以看成近似的完全二叉树。表示堆的数组包括两个属性:A.length数组元素的个数,A.heapSize表示多少个元素存在数组中。这里的关系是:

    相关 排序-Java实现

    堆排序思想 对于给定的n个数据,初始时将n维数组看成一颗二叉树,若需要从小到大排序,将其调整为小顶堆(若从大到小排序,调整为大顶堆),输出堆顶元素,然后将堆的最后一个元素