排序算法之直接选择排序

直接选择排序是最简单直观的排序算法,属于选择排序。

直接算法的排序思路:

  1. 第一趟,程序将记录定位在第一个数据上,拿第一个数据依次和后面的数据进行比较,如果第一个数据大,交换,依次类推。经过第一趟比较,这组数据中最小的数据被选出来,排在第一位。
  2. 第二趟,程序将记录定位在第二个数据上,拿第二个数据依次和后面的数据比较,同样地,第二个数据大就交换。经过第二次比较,这轮最小的书被选出来,放在了第二位。

  这样经过n-1次比较,这组数据就会变得有序。下面是直接选择的排序算法实现。

/**
 * Created by tom on 2017-05-07.
 */
//创建对象数组来作为被排序的对象,在每个对象中加入标识,标识相同的数字
class DataWrap implements Comparable<DataWrap>{ int data; String flag; public DataWrap(int data ,String flag){ this.data=data; this.flag=flag; } @Override public String toString() { return data+flag; } //如果当前data大于dw,返回1;小于和等于返回数值不是1 @Override public int compareTo(DataWrap dw) { return this.data>dw.data?1:(this.data==dw.data?0:-1); } } public class SelectSort { public static void SelectSort(DataWrap[] data){ System.out.println("开始排序"); int arrayLength=data.length; for (int i = 0; i < arrayLength-1; i++) {for (int j = i+1; j <arrayLength ; j++) { if(data[i].compareTo(data[j])>0){ //如果data[i]>data[j],则交换顺序 DataWrap temp=data[i]; data[i]=data[j]; data[j]=temp; } } } } public static void main(String[] args){ DataWrap[] dataWrap={ new DataWrap(21,""), new DataWrap(25,""), new DataWrap(31,""), new DataWrap(21,"*"), new DataWrap(1,""), new DataWrap(71,""), new DataWrap(2,""), }; System.out.println("排序之前"); System.out.println(java.util.Arrays.toString(dataWrap)); SelectSort(dataWrap); System.out.println("排序之后"); System.out.println(java.util.Arrays.toString(dataWrap)); } }

程序输出结果:

排序之前
[21, 25, 31, 21*, 1, 71, 2]
开始排序
排序之后
[1, 2, 21, 21*, 25, 31, 71]

从这个结果来看,这种选择排序好像是稳定的,两个21的顺序没有乱,其实仔细想就会发现,上面这种实现的直接排序算法还可以进一步优化,在数据项比较的时候:

 if(data[i].compareTo(data[j])>0){
                    //如果data[i]>data[j],则交换顺序
                    DataWrap temp=data[i];
                    data[i]=data[j];
                    data[j]=temp;
                }

每一次比较data[i]和data[j]时,当data[i]>data[j]时,就会进行交换,相当是每一趟不止进行了一次数据项的交换,这样效率比较低,其实每一次比较只需要保留数组的索引,在这一趟结束时交换数据项就可以了,这样每一趟最多进行一次数据项交换。以下是优化后的算法实现:

/**
 * Created by tom on 2017-05-07.
 */
class DataWrap implements Comparable<DataWrap>{
    int data;
    String flag;
    public DataWrap(int data ,String flag){
        this.data=data;
        this.flag=flag;
    }

    @Override
    public String toString() {
        return data+flag;
    }

    //如果当前data大于dw,返回1;小于和等于返回数值不是1
    @Override
    public int compareTo(DataWrap dw) {
        return this.data>dw.data?1:(this.data==dw.data?0:-1);
    }
}

public class SelectSort {
    public static void SelectSort(DataWrap[] data){
        System.out.println("开始排序");
        int arrayLength=data.length;

        for (int i = 0; i < arrayLength-1; i++) {
            //minIdex只保留最小值的索引
            int minIndex=i;
            for (int j = i+1; j <arrayLength ; j++) {
                if(data[minIndex].compareTo(data[j])>0){
           //这里保留了索引的值 minIndex
=j; } } //每趟最多交换一次 if (minIndex!=i){ DataWrap temp=data[i]; data[i]=data[minIndex]; data[minIndex]=temp; } } } public static void main(String[] args){ DataWrap[] dataWrap={ new DataWrap(21,""), new DataWrap(25,""), new DataWrap(31,""), new DataWrap(21,"*"), new DataWrap(1,""), new DataWrap(71,""), new DataWrap(2,""), }; System.out.println("排序之前"); System.out.println(java.util.Arrays.toString(dataWrap)); SelectSort(dataWrap); System.out.println("排序之后"); System.out.println(java.util.Arrays.toString(dataWrap)); } }

排序之前
[21, 25, 31, 21*, 1, 71, 2]
开始排序
排序之后
[1, 2, 21*, 21, 25, 31, 71]

从结果可以看出,真正的直接选择排序并不是稳定的排序算法。

posted @ 2017-05-08 19:31  Archieyao  阅读(653)  评论(0编辑  收藏  举报