排序——选择排序

简介

选择排序是一种常用的排序方法,其排序思想是这样的:对于数组n,第一趟排序取出n个元素中最小的元素,第二趟排序取出剩余n-1个元素中最小的元素……直到整个数组取完为止。常用的选择排序有简单选择排序、树形选择排序和堆排序。

注意:选择排序是一种不稳定的排序算法

一、简单选择排序

简单选择排序是一种比较好理解的选择排序,其实现思想也非常简单:对于数组n,第一趟排序找出n个元素中最小的元素与第1个元素交换,第二趟排序找出剩下的n-1个元素中最小的元素与第2个元素交换…直到整个序列有序,算法的时间复杂度为O(n2)。这种方法很简单,所以不做过多的解释。

二、树形选择排序

树形选择排序又称锦标赛排序,是一种按照锦标赛的思想进行选择排序的方法。首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进行两两比较,如此重复,直至选出最小的记录为止。
树形选择排序的过程如下图所示:
这里写图片描述
时间复杂度是O(nlog2n)

三、堆排序

这里首先介绍一下堆这种结构,堆是满足下列这种要求的二叉树:任意一节点的值都大于等于(小于等于)其左右子节点的值。且分别称为最大堆、最小堆。
堆排序的过程:
①将n个元素建立成堆(这将用到下面的筛选②)
②筛选最大元素:第一趟将堆顶元素和nums[n-1]交换,并将nums[0]~nums[n-2]重建堆。第二趟将堆顶元素和nums[n-2]交换,并将nums[0]~nums[n-3]重建堆…直到排序完成。
堆排序的算法时间复杂度为O(nlog2n)

堆排序和快排的比较

由于堆排序最坏情况下的复杂度也为O(nlog2n),高于快排最坏情况下的O(n2),所以如果考虑到最坏情况,还是选择堆排序比较好。


附代码:

1.简单选择排序

class SelectSortTool{

    public static void selectSort(int[] nums){
        int temp;
        int minuIndex;//找到的最小的数的下标
        for(int i = 0 ;i < nums.length - 1; i ++){
            minuIndex = i+1;
            //搜索最小数的下标
            for(int j = i + 1 ; j < nums.length ; j ++){
                if(nums[j] < nums[minuIndex]){
                    minuIndex = j;
                }
            }
            //交换
            temp = nums[minuIndex];
            nums[minuIndex] = nums[i];
            nums[i] = temp;
        }
    }

}

2.堆排序

class HeapSortTool{

    public static void HeapAdjust(int[] nums, int start, int last){
        int temp ;
        //调整从start到last之间的堆
        for(int i = start ; i <= last ; i ++ ){
            //调整以i为根的子树
            if((2*i+2 <= last && nums[2*i+1] > nums[i] && nums[2*i+1] >= nums[2*i+2])||
                    (2*i+1 <= last && 2*i+2 > last && nums[2*i+1] > nums[i])){
                //左右子节点都存在且左节点更大 或者 只有左子节点存在且更大
                temp = nums[i];
                nums[i] = nums[2*i+1];
                nums[2*i+1] = temp;
            }else if(2*i+2 <= last && nums[2*i+2] > nums[i] && nums[2*i+2] > nums[2*i+1]){
                //右子节点更大
                temp = nums[i];
                nums[i] = nums[2*i+2];
                nums[2*i+2] = temp;
            }
            if(i*2+1 > last)
                break;
        }
    }

    public static void HeapSort(int[] nums){
        //建立堆
        for(int i = nums.length/2 + 1; i >= 0 ; i --){
            HeapAdjust(nums, i, nums.length-1);
        }
        int temp;
        for(int i = nums.length-1 ; i > 0 ; i --){
            temp = nums[0];
            nums[0] = nums[i];
            nums[i] = temp;
            HeapAdjust(nums, 0, i-1);
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值