堆排序(Heap Sort)是指利用堆积树(堆)这种数据结构所涉及的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值不大于其父节点的值。

算法描述:

1,将初始待排序序列(R1,R2....Rn)构建成大根堆,此堆为初始的无序列。

2,将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序列(R1,R2,.....Rn-1)和新的有序列(Rn),且满足R[1,2...Rn-1]<=R[n]。

3,由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序列(R1,R2,...Rn-1)调整为新堆,然后再次将R[1]与无序列最后一个元素交换,得到新的无序列(R1,R2,...Rn-2)和新的有序列(Rn-1,Rn)。不断重复此过程直到有序列的元素个数为n-1,则整个排序过程完成。

动图演示:

代码实现:

public class Sort{
     public static void swap(int[] arr,int i,int j){
          int temp=arr[i];
          arr[i]=arr[j];
          arr[j]=temp;
     }

     public static void printArr(int[] arr){
          for(int i:arr){
               System.out.print(i+" ");
          }
     }

     //建立最大堆
     public static void makeMaxHeap(int[] arr){
          int len=arr.length;
          //(len/2-1)表示倒数第二层最后一个元素的下标
          for(int i=len/2-1;i>=0;i--){
               shiftDown(arr,i,len);
          }
     }

     //元素下移操作
     public static void shiftDown(int[] arr,int i,int len){
          //len是剩余的无序列中元素的个数
          //maxIndex记录节点,左节点,右节点中元素最大的下标
          int maxIndex=i;
          //left是节点i的左节点下标
          int left=2*i+1;
          //right是节点i的右节点下标
          int right=2*i+2;
          if(left<len&&arr[left]>arr[maxIndex]){
                maxIndex=left;
          }
          if(right<len&&arr[right]>arr[maxIndex]){
                maxIndex=right;
          }
          if(maxIndex!=i){           
                swap(arr,i,maxIndex);
                len--;
                //交换之后的元素继续下移操作
                shiftDown(arr,maxIndex,len);
          }
     }

     public static void heapSort(int[] arr){
          int len=arr.length;
          //建立最大堆
          makeMaxHeap(arr);
          while(len>0){
               swap(arr,0,len-1);
               len--;
               shiftDown(arr,0,len);
          }
     }
 
     public static void main(String[] args){
          int[] arr=new int[]{4,3,38,5,47,15,36,26,27,2,46,44,19,50,48};
          heapSort(arr);
          printArr(arr);
     }
}

 

 posted on 2018-07-25 21:30  会飞的金鱼  阅读(179)  评论(0)    收藏  举报