Java练习:简单粗暴法选择排序

返回 Java编程练习目录


穷举算法、枚举算法或蛮力算法等,在解决问题优先的指导方针下,是很有意义的。

1.粗暴到底

嗨,baby,把待排序的数组 int[] arr按照非降序(前面的数小于或等于后面的数)排列.
最为简单粗暴的方式:
  1. 奢侈地使用辅助空间arr2,
  2. 用眼睛从头到尾地扫描一次arr,从中选择一个最小的元素,而且放入arr2[0],而且在arr原位置打个叉(或标记为Max);
  3. 依此类推,扫描n次。
package algorithm.sorting;
public class MySelectionSort extends IntSort{    
    @Override public int[] sort(int[] arr){ 
        int[] arr2 = new int[arr.length];//奢侈地使用一个辅助空间arr2
        for(int i=0;i<arr2.length;i++){
            arr2[i] = scan(arr);
        }
        return arr2;
    }//end sort 
    /**
     * 用眼睛从头到尾地扫描一次arr,从中选择一个最小的元素并放入arr2[0],
     * 将arr原来最小的元素位置标记为Max;
     */
    private int scan(int[] arr){
        int min=arr[0];
        int index =0;
        for(int i=0;i<arr.length;i++){
            if(min>arr[i]) {
                min=arr[i];
                index=i;
            }
        }
        arr[index]=0X7fffffff;
        return min;
    }
}
你还能够再粗暴一点吗?
  • 辅助空间arr2,空间复杂度为O(n)。就地 (in-place) 排序指排序时仅借用常数个辅助内存空间即空间复杂度为O(1),而排序工作主要在数组arr自己的空间中通过元素交换位置或移动位置完成。有没有用空间换时间的例子?
  • 在选择出一个最小的元素后,我们能不能把剩下的数拷贝到辅助空间arr3中,据说有些人用筛子解题。
  • 为什么把最小元素的位置标记为int的最大值0X7fffffff,我找出当前arr的Max不行吗?
好吧,我们上面的选择排序MySelectionSort已经够了。 sort的循环一个n,循环中调用的scan一个n,总共需要比较n*n次,时间复杂度为O(n 2)。

2.简单选择排序

简单选择排序或 选择排序(SelectionSort),在arr中拿出一个位置(第一趟排序拿出arr[0]),向后面扫描过去,遇到比自己当前值小的就交换。如{5,7,6,2,3,8,4,1,9},第一趟中先将5与2换位,再将2与1换位,结果为{1,7,6,5,3,8,4,2,9}。第二趟,以arr[1]为起点,交换交换得到{1,2,7,6,5,8,4,3,9}...
练习11-5:写出{5,8,5,4,3,5,2,7,1,9}在第一、二趟排序后的结果。编写SelectionSort的sortDeme(),打印每一趟排序的结果。
package algorithm.sorting;
import static tips.Print.*;//<span style="font-family: Arial, Helvetica, sans-serif;">pln(int[])</span>

/**
 * SelectionSort.java.
 * 简单选择排序。是蛮力算法、本地排序、基于比较的排序。时间复杂度为O(n*(n-1)/2)=O(n2)
 * @author yqj2065
 * @version 0.1
 */
public class SelectionSort extends IntSort{
    /**
     * 简单选择排序,选择最小元素-交换
     */
    public static void sortDeme(){
        int[] arr  = new int[]{5,7,6,2,3,8,4,1,9};
        p("排序前:");
        pln(arr);
        pln("排序...");
        for(int i=0; i< arr.length; i++){
            int min =arr[i];//可以省略这一辅助空间
            for(int j=i+1; j< arr.length; j++){
                if( min > arr[j]){ //选择最小的数
                    min =arr[j];
                    IntSort.swap(arr ,i, j);                    
                }//end if
            }
            p("第"+i+"趟:");
            pln(arr);
        }
    }//end sort


    
    @Override public int[] sort(int[] arr){        
       //
    }     
}
排序前:[5, 8, 5, 4, 3, 5, 2, 7, 1, 9]
排序...
第0趟:[1, 8, 5, 5, 4, 5, 3, 7, 2, 9]
第1趟:[1, 2, 8, 5, 5, 5, 4, 7, 3, 9]
第2趟:[1, 2, 3, 8, 5, 5, 5, 7, 4, 9]
第3趟:[1, 2, 3, 4, 8, 5, 5, 7, 5, 9]
第4趟:[1, 2, 3, 4, 5, 8, 5, 7, 5, 9]
第5趟:[1, 2, 3, 4, 5, 5, 8, 7, 5, 9]
第6趟:[1, 2, 3, 4, 5, 5, 5, 8, 7, 9]
第7趟:[1, 2, 3, 4, 5, 5, 5, 7, 8, 9]
第8趟:[1, 2, 3, 4, 5, 5, 5, 7, 8, 9]
第9趟:[1, 2, 3, 4, 5, 5, 5, 7, 8, 9]

练习11-5:编写@Override public int[] sort(int[] arr)
提示:剩下的最后一个元素不动;
思考:上面第7趟已经完成排序,怎样避免多余的趟?

结语:

简单选择排序是蛮力算法、就地排序、基于比较的排序。
选择排序的时间复杂度为O(n*(n-1)/2)=O(n2),比较次数不到前面的例子MySelectionSort的n*n次的一半——虽然都是O(n2)。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值