排序算法之堆排序--Java语言

 

堆排序算法首先将所有元素(从未排序的数组)插入堆中,然后从堆的根节点依次删除,直到堆空为止。本文主要利用现有数组进行就地排序,具体做法是,当删除一个元素时,只是将数组中的第一个元素与最后一个元素交换位置而不是移除,同时减小堆的大小,即数组大小,然后再对第一个元素进行堆化。持续这个过程直到剩余元素为1.

在数组中直接进行堆排序,需要知道几个参数,即最后一个元素的位置是i=count-1,count为数组大小,则最后一个元素的双亲位置为(count-1)/2。任意一个节点j的左子节点位置l=2*j+1,右子节点位置r=2*j+2.

代码:

  1. public class HeapSort {

  2. public static void swap(int[] data,int i,int j)

  3. {

  4. if(i==j)

  5. return;

  6. data[i]=data[i]+data[j];

  7. data[j]=data[i]-data[j];

  8. data[i]=data[i]-data[j];

  9. }

  10.  
  11. public static int[] heapSort(int[] data)

  12. {

  13. for(int i=0;i<data.length;i++)//控制堆大小。

  14. {

  15. //每次遍历创建最大堆,并且将堆顶元素放至最后一个,并将遍历的最后一位位置逐个左移。

  16. createMaxHeap(data,data.length-1-i);//堆化

  17. swap(data,0,data.length-1-i);//交换第一个元素与最后一个元素,即获取当前最大值

  18. print(data);

  19. }

  20. return data;

  21. }

  22.  
  23. public static void createMaxHeap(int[] data,int lastIndex)

  24. {

  25. for(int i=(lastIndex-1)/2;i>=0;i--)

  26. {

  27. //保存当前正在判断的节点

  28. int k=i;

  29. //若当前节点存在

  30. while(2*k+1<=lastIndex)

  31. {

  32. //biggerIndex总是记录较大节点的值,先赋值为当前判断节点的左子节点

  33. int biggerIndex=2*k+1;

  34. if(biggerIndex<lastIndex)

  35. {

  36. //若右子节点存在,否则此时biggerIndex应该等于lastIndex

  37. if(data[biggerIndex]<data[biggerIndex+1])

  38. {

  39. //若右子节点值比左子节点值大,则biggerIndex记录的是右子节点的值

  40. biggerIndex++;

  41. }

  42.  
  43. }

  44. if(data[k]<data[biggerIndex])

  45. {

  46. //若当前节点值比子节点最大值小,则交换两者的值,交换后将biggerIndex值赋给k

  47. swap(data,k,biggerIndex);

  48. k=biggerIndex;

  49. }

  50. else

  51. break;

  52. }

  53. }

  54. }

  55.  
  56. public static void print(int[] data)

  57. {

  58. for(int i=0;i<data.length;i++)

  59. System.out.print(data[i]+" ");

  60. System.out.println();

  61. }

  62.  
  63. public static void main(String[] args)

  64. {

  65. int[] data= {89, 66, 39, 78, 40, 56, 3, 13, 20, 95};

  66. System.out.println("堆排序的序列变化:");

  67. int[] ans=heapSort(data);

  68. System.out.println("堆排序后的序列:");

  69. for(int i=0;i<data.length;i++)

  70. System.out.print(data[i]+" ");

  71. }

  72.  
  73. }

测试结果:

  1. 堆排序的序列变化:

  2. 40 89 56 78 66 39 3 13 20 95

  3. 20 78 56 40 66 39 3 13 89 95

  4. 13 66 56 40 20 39 3 78 89 95

  5. 3 40 56 13 20 39 66 78 89 95

  6. 3 40 39 13 20 56 66 78 89 95

  7. 3 20 39 13 40 56 66 78 89 95

  8. 13 20 3 39 40 56 66 78 89 95

  9. 3 13 20 39 40 56 66 78 89 95

  10. 3 13 20 39 40 56 66 78 89 95

  11. 3 13 20 39 40 56 66 78 89 95

  12. 堆排序后的序列:

  13. 3 13 20 39 40 56 66 78 89 95

猜你喜欢

转载自blog.csdn.net/It_BeeCoder/article/details/82385998