堆排序算法 java 实现

白话经典算法系列之七 堆与堆排序

Java排序算法(三):堆排序

算法概念

堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。堆排序是不稳定的排序方法,辅助空间为O(1), 最坏时间复杂度为O(nlog2n) ,堆排序的堆序的平均性能较接近于最坏性能。

算法思想

  1. 建立最小堆;

  2. 取出堆顶元素,顺序放到待排序数组中;将堆底元素放到堆顶,并重新调整堆;

  3. 重复步骤 2 ,直至堆中所有元素全部取完;


参考的两篇文章都是将堆顶元素和堆底元素互换,最后存放堆的数组就变成了有序数组。

  1. 建立最大堆;
  2. 将堆顶元素和堆底元素互换;重新调整除堆底有序元素外的堆;
  3. 重复步骤 2 ,直至堆中全部元素都变有序;

算法实现

  1. package com.lygedi.sort;
  2. import org.apache.commons.lang.ArrayUtils;
  3. import org.apache.commons.lang.StringUtils;
  4. public class HeapSort {
  5. public static void main(String[] args) {
  6. int a[] = { 49, 38, 65, 9, 76, 13, 27, 49, 8, 34, 12, 64, 49, 56, 2, 51, 13, 5, 4, 62, 99, 98, 54, 56, 17, 17,
  7. 18, 23, 34, 56, 15, 35, 25, 53, 51 };
  8. int[] b = a.clone();
  9. HeapSort hs = new HeapSort();
  10. hs.sortByMinHeapClass(a);
  11. hs.sortByOneMothed(b);
  12. System.out.println(a.length);
  13. for (int i = 0; i < a.length; i++)
  14. System.out.println(Integer.toString(i) + "-" + a[i] + "--" + b[i]);
  15. }
  16. public void sortByMinHeapClass(int[] list) {
  17. MinHeap mh = new MinHeap(list);
  18. System.out.println(mh);
  19. for (int i = 0; i < list.length; i++) {
  20. list[i] = mh.pushTop();
  21. }
  22. }
  23. public void sortByOneMothed(int[] list){
  24. for(int i = list.length-1; i>=0; i--){
  25. initMaxHeap(list,0,i);
  26. swap(list,0,i);
  27. }
  28. }
  29. private void initMaxHeap(int[] list,int startIndex,int stopIndex){
  30. int leftChild, rightChild;
  31. boolean isChanged = false;
  32. for(int i=startIndex;i<=stopIndex;i++){
  33. leftChild = i*2 + 1;
  34. rightChild = i*2 + 2;
  35. if(leftChild<=stopIndex && list[i]<list[leftChild]){
  36. swap(list,i,leftChild);
  37. isChanged = true;
  38. }
  39. if(rightChild<=stopIndex && list[i]<list[rightChild]){
  40. swap(list,i,rightChild);
  41. isChanged = true;
  42. }
  43. if(i>startIndex && isChanged){
  44. i = (i - 1)/2 - 1;
  45. isChanged = false;
  46. }
  47. }
  48. }
  49. private void swap(int[] list,int i,int j){
  50. int temp = list[i];
  51. list[i] = list[j];
  52. list[j] = temp;
  53. }
  54. }
  55. class MinHeap {
  56. private int[] heap;
  57. public MinHeap(int[] list) {
  58. heap = list;
  59. fixHeap();
  60. }
  61. public int pushTop() {
  62. int top = heap[0];
  63. int tail = heap[heap.length - 1];
  64. if (heap.length > 1) {
  65. int[] newheap = ArrayUtils.subarray(heap, 0, heap.length - 1);
  66. newheap[0] = tail;
  67. heap = newheap;
  68. fixHeap();
  69. }
  70. return top;
  71. }
  72. private void swap(int[] list,int i,int j){
  73. int temp = list[i];
  74. list[i] = list[j];
  75. list[j] = temp;
  76. }
  77. private void fixHeap() {
  78. int leftChild, rightChild;
  79. boolean isChanged = false;
  80. for (int i = 0; i < heap.length; i++) {
  81. leftChild = i * 2 + 1;
  82. rightChild = i * 2 + 2;
  83. if (leftChild <= heap.length - 1 && heap[i] > heap[leftChild]) {
  84. swap(heap,i,leftChild);
  85. isChanged = true;
  86. }
  87. if (rightChild <= heap.length - 1 && heap[i] > heap[rightChild]) {
  88. swap(heap,i,rightChild);
  89. isChanged = true;
  90. }
  91. //如果子节点进行了调整,则要对父节点重新进行调整
  92. if (isChanged && i > 0) {
  93. i = (i - 1) / 2 - 1;
  94. isChanged = false;
  95. }
  96. }
  97. }
  98. public String toString() {
  99. StringBuilder sb = new StringBuilder();
  100. int count = heap.length;
  101. int grade = (int) Math.ceil(java.lang.StrictMath.pow(count, 1.0 / 2));
  102. String padding = "**";
  103. int index = 0;
  104. for (int i = 1; i <= grade; i++) {
  105. int padNum = (int)Math.pow(2, grade-i+1)-1;
  106. String gradePadding = StringUtils.repeat(padding, padNum);
  107. for (int j = 1; j <= Math.pow(2, i - 1); j++) {
  108. if (index < count) {
  109. sb.append(gradePadding);
  110. String paddingInt = StringUtils.leftPad(Integer.toString(heap[index]), padding.length(), "*");
  111. sb.append(paddingInt);
  112. index++;
  113. sb.append(gradePadding);
  114. sb.append(padding);
  115. }
  116. }
  117. sb.append("\r\n\r\n\r\n");
  118. }
  119. return sb.toString();
  120. }
  121. }

堆排序算法 java 实现的更多相关文章

  1. 排序系列 之 堆排序算法 —— Java实现

       基本概念: 二叉堆是完全二叉树或者是近似完全二叉树. 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆. 当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆. 一般将二叉堆简称 ...

  2. 堆排序算法(Java实现)

    将待排序的序列构造成一个大顶堆(从大到小排要构造成小顶堆).此时,整个序列的最大值就是堆顶的根节点,将他和末尾元素交换,然后将剩余的length-1个节点序列重新构造成新的堆.重复执行,便能得到一个有 ...

  3. 算法-java代码实现堆排序

    堆排序 第7节 堆排序练习题 对于一个int数组,请编写一个堆排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2 ...

  4. 堆排序算法的java实现

         堆积排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素.堆排序是不稳定的排序方法,辅助空间为O(1), 最坏时间复杂度为O ...

  5. 必须知道的八大种排序算法【java实现】(三) 归并排序算法、堆排序算法详解

    一.归并排序算法 基本思想: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并 ...

  6. 排序算法入门之堆排序(Java实现)

    堆排序 在学习了二叉堆(优先队列)以后,我们来看看堆排序.堆排序总的运行时间为O(NlonN). 堆的概念 堆是以数组作为存储结构. 可以看出,它们满足以下规律: 设当前元素在数组中以R[i]表示,那 ...

  7. 【java排序】 归并排序算法、堆排序算法

    一.归并排序算法 基本思想: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并 ...

  8. 八大排序算法Java实现

    本文对常见的排序算法进行了总结. 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排 ...

  9. 排序算法(Java实现)

    这几天一直在看严蔚敏老师的那本<数据结构>那本书.之前第一次学懵懵逼逼,当再次看的时候,发觉写的是非常详细,非常的好. 那就把相关的排序算法用我熟悉的Java语言记录下来了.以下排序算法是 ...

随机推荐

  1. websocket 实现聊天功能

    <html> <head> <base href="<%=basePath%>"> <title>webscoket t ...

  2. scrapy爬虫笔记(二)------交互式爬取

    开始网页爬取:(1)交互式爬取 首先,我们使用scrapy建立起爬虫的框架.在命令行中输入 scrapy shell “url” 如:scrapy shell “http://www.baidu.co ...

  3. c# 反射事件

    被反射类中: public delegate void CompeletedHandler(); public static event CompeletedHandler AnalysisCompe ...

  4. R中一切都是vector

    0.可以说R语言中一切结构体的基础是vector! R中一切都是vector,vecotor的每个component必须类型一致(character,numeric,integer....)!vect ...

  5. CentOS7 编译安装 Mariadb (实测 笔记 Centos 7.0 + Mariadb 10.0.15)

    环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7.0-1406-x86_64-DVD.iso 安装步骤: 1.准备 1.1 显示系统版 ...

  6. css解决div的各种浏览器兼容性问题

    方法一: min-height:500px;/*解决ie8.9.ff.chromet*/ height:100%;/*解决ie6.7*/ _height:500px;/*解决ie6超出自动溢出*/ 方 ...

  7. Mac&iOS之多线程--转自http://geeklu.com/2012/02/thread/

    http://geeklu.com/2012/02/thread/ 首先循环体的开始需要检测是否有需要处理的事件,如果有则去处理,如果没有则进入睡眠以节省CPU时间. 所以重点便是这个需要处理的事件, ...

  8. 真机测试及布署Code Sign error问题总结

    Code Sign error: Certificate identity 'iPhone Developer: idf (XR9HN3TD7E)' appears more than once in ...

  9. Runtime详解

    http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/

  10. Ubuntu上安装Karma失败对策

    在Ubuntu上安装Karma遇到超时 timeout 错误.Google了一下,国外的码农给了一个快捷的解决方案,实测可行,贴在这里: sudo apt-get install npm nodejs ...