选择排序从入门到精通——Java实现

选择排序

算法实现原理

1、选取出 n 条记录中最小的记录与第一条记录进行交换 —— 循环的第一趟
2、选取出除第一条记录以外的 n-1 条记录中最小的记录与第二条记录进行交换 —— 循环的第二趟
3、以此类推直到整个数组全部遍历排序完成。

与冒泡排序的对比

选择排序可以看成冒泡排序的改进版本
冒泡排序实际上是将数据从右至左排序完成(从右至左、从大到小进行交换排序),而快速排序是将数据从左到右排序完成(从左至右、从小到大进行交换排序),虽然选择排序相对于冒泡排序将交换次数从 O ( n 2 ) O(n^2) O(n2)减少到了 O ( n ) O(n) O(n),但是比较次数还是保持 O ( n 2 ) O(n^2) O(n2)

算法复杂度

比较次数 O ( n 2 ) O(n^2) O(n2)——比较次数与关键字的初始状态无关,总的比较次数 N = ( n − 1 ) + ( n − 2 ) + . . . + 1 = n ( n − 1 ) / 2 N=(n-1)+(n-2)+...+1=n(n-1)/2 N=(n1)+(n2)+...+1=n(n1)/2

交换次数 O ( n ) O(n) O(n)——最好情况是,已经有序,交换 0 次;最坏情况交换 n-1 次,逆序交换 n / 2 n/2 n/2 次。

算法稳定性

选择排序是不稳定,当数据为2,3,2,1,4,5时就会出现第一次出现的2会被交换到第二次出现的2后面,这样就造成了排序并没有按照相同数据按照初始的顺序进行排序的要求。

然而冒泡排序却不会出现这样的问题,因为冒泡排序是相邻的两个元素进行比较交换,当数据相等时是不进行操作的所以没有影响相同数据的初始顺序,也就是说冒泡排序是稳定的。

算法Java实现

/**
     * @Author zhuangyan
     * @Description //TODO 选择排序
     * @Date 10:43 2020/3/9
     * @Param []
     * @return void
     **/
    public static void SelectSort(){
        int temp;//临时变量
        //创建新的数组
        int[] arr = new int[]{4,7,1,6,2,8,432,67,26,65,31765,765,5235,54756,643,52345,76};
        //进行排序
        for(int i = 0;i < arr.length-1;i++){
            int min = i;//选出"最小"下标(数据的第一条)
            for(int j = i+1;j < arr.length;j++){
                //寻找相对最小值对应下标
                if(arr[min]>arr[j]){
                    min = j;
                }
            }
            //如果寻找到最小值,将最小值与当前位置交换
            if(min != i){
                temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
            }
        }
        //输出
        System.out.print("选择排序:");
        for(int i : arr){
            System.out.print(i);
            System.out.print(" ");
        }
        System.out.println();
    }

优化

对于选择排序的优化,其实是对选择排序的深入理解的一个过程,相信看到了这里大家都知道了选择排序在每一次从左到右的循环周期内都是确定了一个最小的元素放置在前面,相信这时候大家已经想到了,既然从左到右可以选出最小的,那一定可以选出最大的。是的,本次优化的出发点也是从这一思想开始,不多说上代码。

    /**
     * @Author zhuangyan
     * @Description //TODO 选择排序优化
     * @Date 10:43 2020/3/9
     * @Param []
     * @return void
     **/
    public static void OptimizeSelectSort(){
        int temp;//临时变量
        //创建新的数组
        int[] arr = new int[]{4,7,1,6,2,8,432,67,26,65,31765,765,5235,54756,643,52345,76};
        int left = 0;//数据项的左侧下标
        int right = arr.length - 1;//数据项的右侧下标
        //进行排序
        while(left < right){
            int min = left;//初始化最小标兵
            int max = left;//初始化最大标兵
            //无需与本身进行比较无意义所以 i 从 left+1 开始计算
            for(int i = left + 1;i <= right;i++){
                if(arr[min] > arr[i]){
                    min = i;
                }
                if(arr[max] < arr[i]){
                    max = i;
                }
            }
            //选取出最小值与第一元素进行交换
            if(min != left){
                temp = arr[left];
                arr[left] = arr[min];
                arr[min] = temp;
            }
            //这一步很重要,最开始没有考虑到,导致测试用例不能100%
            //这一步的意义其实很简单,假如最大值在最左测,此时程序走到这里时
            //最大的值已经被上面的步骤替换到了原本最小值所对应的下标处
            //如果继续使用left作为最大值下标就会导致最小值被交换到后面
            if(max == left){
                max = min;
            }
            if(max != right){
                temp = arr[right];
                arr[right] = arr[max];
                arr[max] = temp;
            }
            //左侧指针右移(此处的指针是本人的类比,这样比较形象,其实是数组的下标)
            left++;
            //右侧指针左移(此处的指针是本人的类比,这样比较形象,其实是数组的下标)
            right--;
        }
        //输出
        System.out.print("选择排序优化:");
        for(int i : arr){
            System.out.print(i);
            System.out.print(" ");
        }
        System.out.println();
    }

具体代码详见github:https://github.com/zytwist/algorithm

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会编程的羽流云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值