排序算法值--堆排序

        堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:

  Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2]

  即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。

          堆分为大顶堆和小顶堆:

                  
                            大顶堆                                                                                小顶堆

算法思想(以大顶堆为例):
1.将长度为n的待排序的数组进行堆有序化构造成一个大顶堆(将数组--》转化为一个大顶堆)
 
2.将根节点与尾节点交换并输出此时的尾节点(交换节点)
 
3.将剩余的n -1个节点重新进行堆有序化(交换节点后继续有序化)
 
4.重复步骤2,步骤3直至构造成一个有序序列(重复2,3步骤)
 
假设待排序数组为[20,50,10,30,70,20,80]

具体程序实现:
public  class  HeapSort {
     private  static  void  heapSort( int [] arr) {
         int  len = arr.length - 1 ;    //记得-1
         for ( int  i = len/ 2  1 ; i >= 0 ; i --){  //堆构造,将数组转换为大顶堆
             heapAdjust(arr,i,len);
         }
         while  (len >= 0 ){
             swap(arr, 0 ,len--);     //将堆顶元素与尾节点交换后,长度减1,尾元素最大
             heapAdjust(arr, 0 ,len);     //,别忘了这一步,再次对堆进行调整
         }
     }
 
public  static   void  heapAdjust( int [] arr, int  i, int  len){
     int  left,right,j ;
     while ((left =  2 *i+ 1 ) <= len){     //判断当前父节点有无左节点(即有无孩子节点,left为左节点)(注意是左节点,而不是右节点,下面才是右节点)
         right = left +  1 ;           //右节点
         j = left;                    //j"指针指向左节点"
         if (j < len && arr[left] < arr[right])     //判断右节点是否存在并且是否右节点大于左节点
             j ++;      //当前把"指针"指向右节点====》下一行的巧妙处理,j不加1,则是与左节点比较,加一则是与右节点比较
         if (arr[i] < arr[j])     //将父节点与孩子节点交换(如果上面if为真,则arr[j]为右节点,如果为假arr[j]则为左节点)
             swap(arr,i,j);
         else          //说明比孩子节点都大,直接跳出循环语句
             break ;
         i = j;        // 子节点与父节点交换位置后,要重新进行堆调整,故将j的值赋予i;
     }
}
     public  static   void  swap( int [] arr, int  i, int  len){//交换两个数
              int  temp = arr[i];
               arr[i] = arr[len];
              arr[len] = temp;
     }
     public  static  void  main(String[] args) {//测试部分
         int  array[] = { 20 , 50 , 20 , 40 , 70 , 10 , 80 , 30 , 60 };
         System.out.println( "排序之前:" );
         for ( int  element : array){
             System.out.print(element+ " " );
         }
         heapSort(array);
         System.out.println( "\n排序之后:" );
         for ( int  element : array){
             System.out.print(element+ " " );
         }
     }
}

看完不懂可参考https://www.cnblogs.com/MOBIN/p/5374217.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值