/**
  *堆排序思路:O(nlogn)
  *    用最大堆,传入一个数组,先用数组建堆,维护堆的性质
  *    再把第一个数与堆最后一个数调换,因为第一个数是最大的
  *    把堆的大小减小一
  *    再  在堆的大小上维护堆的性质
  *    重复操作..
  *
  *
  */
 public  class  HeapSort
 {
     /**
      *静态变量存放堆的大小
      */
     private  static  int  heapsize = 0 ;    

     /**
      *堆排序主方法
      *    构建最大堆,然后进行堆排序
      *    堆排序是把最上面的最大的元素放在最下面,然后再维护上面最大堆的性质
      */
     public  static  void  heapSort(int[] resouceArr)
     {
         //堆的大小
         heapsize = resouceArr.length - 1 ;

         _buildMaxHeap(resouceArr);

         for( int i = resouceArr.length - 1 ; i >= 0 ; i--)
         {
             int temp = resouceArr[0] ;
             resouceArr[0] = resouceArr[i] ;
             resouceArr[i] = temp ; 

             heapsize = heapsize - 1 ;
             _maxHeapify( resouceArr, 0 );
         }
     }

     /**
      *构建最大堆
      *    构建之后还不是有序的,但符合最大堆性质,上面的数一定大于下面的数
      */
     private  static  void  _buildMaxHeap(int[] arr)
     {
         int length = arr.length - 1 ; 

         //从倒数第二排开始维护最大堆性质
         //    当heapsize为偶数时,heapsize要减一
         //    当heapsize为奇数时,不变
         if(length % 2 == 0)
         {
             length--;
         }
         for( int i = length / 2 ; i >= 0  ; i--)
         {
             _maxHeapify(arr , i );
         }
     }

     /**
      *用于维护堆的性质
      *    树形堆在postion的位置向下维护堆的性质,自postion向下满足最大堆的性质
      */
     private  static  void  _maxHeapify(int[] arr,int postion)
     {
         //计算postion的左孩子和右孩子
         postion = postion + 1 ;

         int  l = postion * 2 - 1;
         int  r = postion * 2 ;
         postion = postion - 1 ;

         int largest = maxNumInThreeNum(arr , postion , l , r);

         //如果不满足最大堆性质,则交换值,然后检查树形下方是否满足最大堆性质
         if(largest <= heapsize)
         {
             if( largest != postion)
             {
                 //交换最大值与父节点值
                 int  temp = arr[postion] ;
                 arr[postion] = arr[largest] ;
                 arr[largest] = temp ;
                 //如果子节点变动了,则重新构建已子节点为根的最大堆
                 _maxHeapify(arr , largest);                

             }
         }
     }    

     /**
      *比较数组中的三个数找出最大值
      */
     private  static  int  maxNumInThreeNum(int[] arr ,int a, int b , int c)
     {
         int max = a ;
         //数组长度小于左孩子,最大值为本身
         if(heapsize < b)
         {
             max = a ;
         }
         else if(heapsize >=b && heapsize < c)
         {
             if(arr[a] < arr[b])
             {
                 max = b ;
             }
         }
         else
         {
             if(arr[a] > arr[b])
             {
                 max = a ;
             }
             else
             {
                 max = b ;
             }
             if(arr[max] < arr[c])
             {
                 max = c ;
             }
         }
         return max ;
     }
 }

最新文章

  1. 给空签名包进行签名以及找不到keystore证书链问题的解决方案
  2. gulp 安装 使用 和删除
  3. CI 框架导出文件
  4. RSS(Residual Sum of Squares)的自由度为什么是n-1呢
  5. Java泛型总结(转)
  6. synchronized的理解
  7. Servlet跳转到Jsp的指定div
  8. zoj 1842 Prime Distance
  9. c++ lambda返回类型自动推导的一些需要注意的地方
  10. [TYVJ] P1030 乳草的入侵
  11. Linux学习之rcp命令
  12. shell脚本中$
  13. python 标准库 -- threading
  14. Netty入门之HelloWorld
  15. everything of people’s life can changed in their twenties
  16. css的input文本框的 propertychange、focus、blur
  17. 第一次写html网页
  18. MFC动态创建对话框中的按钮控件并创建其响应消息
  19. 怎么让Word形状里的文字上下左右居中
  20. 2-Sat小结

热门文章

  1. iOS 关闭自动锁屏
  2. 使用 jsPlumb 绘制拓扑图 —— 异步载入与绘制的实现
  3. svn项目导入
  4. Ubuntu安装和配置redis
  5. Codeforces Round #325 (Div. 2) A. Alena&#39;s Schedule 水题
  6. iOS UICollectionView 入门 07 点击cell放大图片
  7. 文件I/O之sync、fsync和fdatasync函数
  8. CCS5 建立SYS/BIOS工程时报错“cannot find file &quot;./configPkg/linker.cmd&quot; bios”的解决方法
  9. 动态修改 C 语言函数的实现
  10. show status详解