选择排序

排序

概念

  • 1.1 排序
    排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
    平时的上下文中,如果提到排序,通常指的是排升序(非降序)。
    通常意义上的排序,都是指的原地排序(in place sort)。

  • 1.2 稳定性
    两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法是具备稳定性的排序
    算法。

    9 , 5 , 2 , 7 , 12 , 2 , 4 , 6 , 9 , 23
    排序后
    前面的 2 依旧在后面的 2 的后面那么称这个算法具有稳定性

选择排序

选择排序实际上就是在遍历的同时选择出最小的元素放在前面,第一次选出最小的放在第一位,第二次选择出次小的放在第二位。。。后面按照相同的步骤就可以使数组有序。

实现

       //直接选择排序
    public static void selectSort(int[] array){
        //这里写成i < array.length - 1;因为当你排完前面的序,最后一个就默认有序了,所以遍历到倒数第二个就结束了
        for (int i = 0; i < array.length-1; i++) {
            int minIndex = i;
            for(int j = i+1;j < array.length - 1;j++){
                //小于号保证了稳定性
                if(array[j] < array[minIndex]){
                    minIndex = j;
                }
            }
            swap(array,i,minIndex);
        }
    }

    private static void swap(int[] array, int i, int minIndex) {
        int t = array[minIndex];
        array[minIndex] = array[i];
        array[i] = t;
    }

总结:
选择排序是稳定的,在比较条件不写等于号就可以避免破坏数据的相对位置!

优化:在遍历的同时记录最大最小值,将最小值放在前面,最大值放在最后,这样效率就会提升,遍历的次数就少了。

   public static void selectSort2(int[] array){
        int left = 0;
        int right = array.length - 1;
        while(left <= right){
            int minIndex = left;
            int maxIndex = left;
            for(int i = left + 1;i <= right;i++){
                if(array[i] < array[minIndex]){
                    minIndex = i;
                }
                if(array[i] > array[maxIndex]){
                    maxIndex = i;
                }
            }
            swap(array,left,minIndex);
            if(maxIndex == left){
                maxIndex = minIndex;
            }
            swap(array,right,maxIndex);
            left++;
            right--;
        }
    }

需要注意的地方:
if(maxIndex == left){
maxIndex = minIndex;
}
这里是为了防止最大的元素在最左边被交换掉位置!比如:

9 5 1 7 3 2
left = 0; right = 5;
maxIndex = 0; minIndex = 2;
如果不加这个条件,当将最小的交换到最左边后,其实maxIndex已经不为0了。而变成了2,所以只要将maxIndex = minIndex;就可以了

注:如有运行错误,请评论一下我尽快更改,谢谢啦!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值