堆排序的JAVA实现和性能分析

来源:互联网 发布:中美黑客大战知乎 编辑:程序博客网 时间:2024/06/14 14:41
package Sort;  import java.util.Arrays;   public class heapsort {        private static int parentIdx(int childIdx) {  //返回父节点下标        return (childIdx - 1) / 2;  //索引从0开始, 注意childIdx=0时返回0      }        private static int leftChildIdx(int parentIdx) {  //返回左孩子下标        return parentIdx*2 + 1;      }          //构建大顶堆    private static void buildMaxHeap(int[] datas)     {          int lastIdx = datas.length -1;  //最后一个元素下标        for(int i=parentIdx(lastIdx); i>=0; i--) // 最外层循环; i初始为最后一个元素的父节点下标,通过控制i的大小来逐步向上构建大顶堆        {              int k = i;  // 第一个父亲节点i暂存于k中            /*boolean isHeap = false;*/                          while(/*!isHeap && */leftChildIdx(k) <= lastIdx) //获得较大孩子元素下标             {  //判断是否有孩子                int biggerChild = leftChildIdx(k);                  if(biggerChild < lastIdx)                                 {    //有两个孩子                       if(datas[biggerChild] <= datas[biggerChild+1])                        //j+1 比较大, 选择大的                       biggerChild++;//j总是保存较大子节点的索引                                           }                  if(datas[k] > datas[biggerChild])                {    //父的比较大                      /*isHeap = true;*/                      break;                 }               else                {                      swap(datas, k, biggerChild);  //较大孩子元素和父亲元素交换                    k = biggerChild;  //将biggerIndex(j)赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右孩子(因为父节点元素发生变化)               }               }          }      }        //保持大顶堆    private static void maintainMaxHeap(int[] datas, int lastIdx) {          int k = 0;  //从根节点开始        while(k <= parentIdx(lastIdx)) {  //终止条件为最后一个元素的父节点            int biggerChild = leftChildIdx(k);              if(biggerChild < lastIdx) {    //有两个孩子                  if(datas[biggerChild] <= datas[biggerChild+1]) { //j+1 比较大, 选择大的                  biggerChild++;                  }              }              if(datas[k] < datas[biggerChild]) {    //父结点比较小                  swap(datas, k, biggerChild);                  k = biggerChild;              } else {                  break;  //跳出while循环体(所有子树都符合大根堆结构)            }          }      }    //排序过程    public static int[] sort(int[] datas) {          buildMaxHeap(datas);  //由datas构建大顶堆        int lastIdx = datas.length - 1;//获取最后一个元素下标          while(lastIdx > 0) {              swap(datas, 0, lastIdx);  //交换根元素和最后一个元素            lastIdx--;              if(lastIdx > 0) {                  maintainMaxHeap(datas, lastIdx);  //维持大顶堆(实际上是将最大的放到树根处)            }          }          return datas;  //此时datas已由小到大排序完成    }      //交换数组中的两个元素    public static void swap(int [] a,int k,int j)    {    int tmp;    tmp=a[k];    a[k]=a[j];    a[j]=tmp;    }      public static void main(String[] args) {          int[] datas = {11,2,5,1,3,4,9,2,7,6,5};//{2, 9, 3, 7, 8, 6, 4, 5, 0, 1};            /*buildMaxHeap(datas);         System.out.println(Arrays.toString(datas));*/            sort(datas);          System.out.println(Arrays.toString(datas));        }      }  



0 0
原创粉丝点击