堆排序算法

 堆排序将是所有的数据先建成一个堆,如大顶堆(最大的数据在堆顶),然后将堆顶数据和序列的最后一个数据交换,然后重新建堆,交换数据,依次下去,就可以排序所有的数据。由于不需要大量的递归或者多维的暂存数组,因此这对于数据量非常巨大的序列是很合适的,比如超过数百万条记录,因为快速排序,归并排序都使用递归来设计算法,在数据量非常大的时候,可能会发生堆栈溢出错误。

堆满足: r(i) >= r(2*i) 且 r(i) >= r(2 * i +1)    i=1,2...

调整是从(arr.length-1) / 2开始,即最后一个节点的父节点开始调整成堆

public class Heap{
    /**
     * 一次堆排序调整
     * @param a 调整的数组
     * @param pos   调整的初始元素位置
     * @param len   调整的最后一个元素位置
     */
      public static void minAdjust(int[] arr, int pos, int len){
          int tmp, child;
          //pos * 2 + 1 <= len判断是否与子节点,注意是 (<= )      tmp = child调整子节点
          for(tmp = arr[pos]; pos * 2 + 1 <= len; pos = child){ 
              child = pos * 2 + 1; //子节点位置
              //有两个子节点,且小的在后一个位置
              if(child < len && arr[child] > arr[child+1]){
                  child ++;
              }
              //子节点小于父节点的情况下,子节点移动到父节点的位置
              if(arr[child] < tmp){
                  arr[pos] = arr[child];
              }else{
                  break;
              }
          }
          arr[child] = tmp;
      }
      public static void minHeap(int[] arry){
          
          int len = arry.length;
          //建立小根堆
          for(int i= len / 2 -1; i >= 0 ; i--){
              minAdjust(arry, i, len-1);
          }
          //交换堆顶元素与堆最后一个元素,形成有序数组
          for(int i= len-1; i>=0; i--){
              int tmp = arry[0];
              arry[0] = arry[i];
              arry[i] = tmp;
              minAdjust(arry, 0, i-1); 
          }
      }
}

 

posted @ 2017-02-28 11:01  huangyichun  阅读(211)  评论(0编辑  收藏  举报