选择排序算法及优化

选择排序算法

选择排序算法的思路是:第一次将集合中最小的数挑选出来放在第一个位置,第二次将集合中最小的数挑选出来放在第二个位置,依此类推。

例如:我们需要对{2,9,5,7,8,0,1,3,4,6}进行排序

经过第1次循环最小位置是:5 结果是:[0, 9, 5, 7, 8, 2, 1, 3, 4, 6];
经过第2次循环最小位置是:6 结果是:[0, 1, 5, 7, 8, 2, 9, 3, 4, 6];
经过第3次循环最小位置是:5 结果是:[0, 1, 2, 7, 8, 5, 9, 3, 4, 6];
经过第4次循环最小位置是:7 结果是:[0, 1, 2, 3, 8, 5, 9, 7, 4, 6];
经过第5次循环最小位置是:8 结果是:[0, 1, 2, 3, 4, 5, 9, 7, 8, 6];
经过第6次循环最小位置是:5 结果是:[0, 1, 2, 3, 4, 5, 9, 7, 8, 6];
经过第7次循环最小位置是:9 结果是:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
经过第8次循环最小位置是:7 结果是:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
经过第9次循环最小位置是:8 结果是:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

选择排序算法初始版本代码如下:

//选择排序算法
public static void main(String[] args) {
   int[] arr={2,9,5,7,8,0,1,3,4,6};
   int min_pos=0;
   for (int j=0;j<arr.length-1;j++ ){
      min_pos=j;
      //找到数组中最小的值对应的索引
      for(int i =j+1;i<arr.length;i++ ){
         if(arr[i]<arr[min_pos])
            min_pos=i;
      }
      //将最小位置和 数组中还未排序的第一个进行交换
      int temp= arr[j];
      arr[j]=arr[min_pos];
      arr[min_pos] = temp;
      System.out.println("经过第"+(j+1)+"次循环最小位置是:"+min_pos+"  结果是:"+Arrays.toString(arr));
   }
   System.out.println(Arrays.toString(arr));
}

我们对代码进行一些优化(每次循环同时找出最大和最小值分别与未排序得最后一个位置和第一个位置进行交换),方法的抽取等操作


 public static void main(String[] args) {
       int arr[] ={2,9,5,7,8,0,1,3,4,6};
       selectionSort(arr);
       System.out.println(Arrays.toString(arr));
}

 public static  void selectionSort(int[] arr){
        int min_pos=0;
        int max_pos=0;
        for (int j=0;j<arr.length/2;j++ ){
            min_pos=j;
            max_pos=arr.length-1-j;
            //找到数组中最小的值对应的索引
            for(int i =j+1;i<arr.length;i++ ){
                min_pos=arr[i]<arr[min_pos]?i:min_pos;
                max_pos=arr[arr.length-i-1]>arr[max_pos]?(arr.length-i-1):max_pos;
            }
            //将最小位置和 数组中还未排序的第一个进行交换
            swap(arr,j,min_pos);
            //将最小位置和 数组中还未排序的最后一个进行交换
            if(j == max_pos ){//处理最大位置刚好被最小数换走的情况
                swap(arr, min_pos, arr.length-j-1);
            } else if(max_pos!=min_pos){//防止最小位置交换后 又换回来
                swap(arr,arr.length-j-1,max_pos);
            }
            System.out.println("经过第"+(j+1)+"次循环最小位置是:"+min_pos+"最大位置是:"+max_pos+"  结果是:"+ Arrays.toString(arr));
        }
    }

	//交换数组中两个数的位置
	public  static  void  swap(int[] arr,int i,int j){
		int temp= arr[j];
		arr[j]=arr[i];
		arr[i] = temp;
	}

运行结果:

经过第1次循环最小位置是:5最大位置是:1 结果是:[0, 6, 5, 7, 8, 2, 1, 3, 4, 9]
经过第2次循环最小位置是:6最大位置是:4 结果是:[0, 1, 5, 7, 4, 2, 6, 3, 8, 9]
经过第3次循环最小位置是:5最大位置是:3 结果是:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
经过第4次循环最小位置是:3最大位置是:6 结果是:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

算法验证

写一个数组生成的方法和数组比较的方法来验证我们的算法是否真的正确

   /*
    验证器
     */
    private static Boolean matcher(int[] arr1,int[] arr2){

        for (int i = 0; i < arr1.length ; i++) {
            if(arr1[i]!=arr2[i]){
                System.out.println(arr2[i]);
                System.out.println(arr1[i]);
                return false;
            }
        }
        return true;
    }

      /*
    *产生随机数组
    */
    public static int[] randomArr(Integer length){
        int arr[] =new int[length] ;
        Random random = new Random();
        for (int i=0;i<length;i++){
            int randomNum = random.nextInt(length);
            arr[i]=randomNum;
        }
        return arr;
    }

主方法中调用

 public static void main(String[] args) {
        int arr[] =randomArr(1000);
      	//拷贝一份用于验证
        int[] copy = Arrays.copyOf(arr, arr.length);
        // 用自己实现的算法排序
        selectionSort(arr);
        //用arrays工具类对复制的数组排序
        Arrays.sort(copy);
        //验证
        System.out.println(matcher(copy, arr));
//        System.out.println(Arrays.toString(arr));
//        System.out.println(Arrays.toString(copy));
    }

经过多次验证,问题不大

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值