选择排序--堆排序

选择排序的基本思想:每一趟 (例如第i趟,i = 0,1,…)在后面第n-i个待排序元素中选出最小元素作为有序序列的第i个元素,直到第n-1趟结束后,所有元素有序。在这里,我们介绍两种具体的选择排序算法:直接选择排序与堆排序。


堆排序的核心是堆调整算法。首先根据初始输入数据,利用堆调整算法shiftDown()形成初始堆;然后,将堆顶元素与堆尾元素交换,缩小堆的范围并重新调整为堆,如此往复。堆排序是一种不稳定的排序算法,其实现如下:

package keking.sort;

/**        
 * Title: 堆排序(选择排序),升序排序(最大堆),依赖于初始序列     
 * Description: 现将给定序列调整为最大堆,然后每次将堆顶元素与堆尾元素交换并缩小堆的范围,直到将堆缩小至1
 * 时间复杂度:O(nlgn)
 * 空间复杂度:O(1) 
 * 稳 定 性:不稳定
 * 内部排序(在排序过程中数据元素完全在内存)
 * @author keking       
 */      
public class HeapSort {

    public static void heapSort(int[] target){
        //调整数组为最大堆
        for(int i = target.length / 2 - 1; i >= 0; i--){
            adjustHeap(target, i, target.length - 1);
        }
        //交换根节点和最后一个元素,完成从小到大的排序
        for(int i = target.length - 1; i > 0; i--){
            int temp = target[i];
            target[i] = target[0];
            target[0] = temp;
            adjustHeap(target, 0, i);
        }
    }

    //将数组调整为最大堆,根节点的值为最大值
    private static void adjustHeap(int[] target, int parent, int length){
        int temp = target[parent];
        int child = parent * 2 + 1; //根节点的左子节点下标
        while(child < length){
            if(child + 1 < length && target[child + 1] > target[child]){ 
                child ++; //右子节点值大,下标指向右子节点
            }
            if(target[child] < temp){
                break; //左右子节点都小于根节点,跳出
            }
            target[parent] = target[child]; //子节点大于根节点,赋值给根节点
            //重新调整子节点下的节点
            parent = child;
            child = parent * 2 + 1;
        }
        //如果根节点和子节点交换过,parent为子节点的下标,将原始根节点的值赋值给子节点
        //如果根节点没有和子节点交换过,根节点还是原来的值
        target[parent] = temp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值