选择排序详解

算法原理如下: 

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

步骤如下:

(1)首先从原始数组中选择最小的1个数据,将其和位于第1个位置的数据交换。
(2)接着从剩下的n-1个数据中选择次小的1个元素,将其和第2个位置的数据交换。
(3)然后,这样不断重复,直到最后两个数据完成交换。至此,便完成了对原始数组的从小到大的排序。

时间复杂度

选择排序的交换操作介于 0 和 (n - 1)次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间。比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

代码如下:

package ca;

import java.util.Arrays;

/***
 * 选择排序
 * */
public class SelectionSort {
    public static void main(String[] args) {
        int[] a = { 1, 8, 5, 32, 45, 9, 25, 36 };
        SelectionSort.selectionSort(a);
    }

    public static void selectionSort(int[] arr) {
        for (int i = 0; i < (arr.length - 1); i++) {
            //先假设每次循环时,最小数的索引为i
            int minIndex = i;
            //每一个元素都和剩下的未排序的元素比较
            int count =0;
            for (int j = i + 1; j < arr.length; j++) {
            	count++;
                if (arr[j] < arr[minIndex]) { //寻找最小数
                    minIndex = j; //将最小数的索引保存
                }
            }
            //经过一轮循环,就可以找出第一个最小值的索引,然后把最小值放到i的位置
            swap(arr, i, minIndex);
            System.out.println(Arrays.toString(arr));
            System.out.println(count);
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

排序步骤如下:

第一轮:

最小数索引为0,也就是第一个数1

第二个数和第一个数比较,8大于1,最小数索引任然为0, 第三个数和第一个数比较,5大于1,最小数索引任然为0,第四个数和第一个数比较,32大于1,最小数索引任然为0,

第五个数和第一个数比较,45大于1,最小数索引任然为0,第六个数和第一个数比较,9大于1,最小数索引任然为0,第七个数和第一个数比较,25大于1,最小数索引任然为0,第八个数和第一个数比较,36大于1,最小数索引任然为0,

第一位数和第一位数互换 [1, 8, 5, 32, 45, 9, 25, 36]

第二轮:

最小数索引为1,也就是第二个数8

第三个数和第二个数比较,5小于8,最小数索引为2,第四个数和第三个数比较,32大于8,最小数索引为2,第五个数和第三个数比较,45大于8,最小数索引为2,

第六个数和第三个数比较,9大于8,最小数索引为2,第七个数和第三个数比较,25大于8,最小数索引为2,第八个数和第三个数比较,36大于8,最小数索引为2,

第三位数和第二位数互换,即5和8互换, [1, 5, 8, 32, 45, 9, 25, 36]

第三轮:

最小数索引为2,也就是第三个数8

第四个数和第三个数比较,32大于8,最小数索引为2,第五个数和第三个数比较,45大于8,最小数索引为2,

第六个数和第三个数比较,9大于8,最小数索引为2,第七个数和第三个数比较,25大于8,最小数索引为2,第八个数和第三个数比较,36大于8,最小数索引为2,

第三位数和第三位数互换,即把 8放入第三位 [1, 5, 8, 32, 45, 9, 25, 36]

第四轮:

最小数索引为3,也就是第四个数32

第五个数和第四个数比较,45大于32,最小数索引为3,第六个数和第四个数比较,9小于45,最小数索引为5,

 第七个数和第六个数比较,25大于9,最小数索引为5,第八个数和第六个数比较,36大于9,最小数索引为5,

第六位和第四位互换,即32和9互换,[1, 5, 8, 9, 45, 32, 25, 36]

第五轮:

最小数索引为4,也就是第五个数45

第六个数和第五个数比较,32小于45,最小数索引为5,第七个数和第六个数比较,25小于32,最小数索引为6,

 第八个数和第七个数比较,36大于25,最小数索引为6,

第七位和第五位互换,即把 25和45互换 [1, 5, 8, 9, 25, 32, 45, 36]

第六轮:

最小数索引为5,也就是第六个数32

第七个数和第六个数比较,45大于32,最小数索引为5,第八个数和第六个数比较,36大于32,最小数索引为5,

第六位和第六位互换, [1, 5, 8, 9, 25, 32, 45, 36]

第七轮:

最小数索引为6,也就是第七个数45

第八个数和第七个数比较,36小于45,最小数索引为7,

第八位和第七位互换,即把36和45互换 [1, 5, 8, 9, 25, 32, 36, 45]

不稳定排序

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Java中,对象数组可以使用`Arrays.sort()`方法进行排序。`Arrays.sort()`方法有多种重载形式,可以根据不同的比较器进行排序,例如: ```java public static <T> void sort(T[] a, Comparator<? super T> c) ``` 其中,`a`参数是待排序的对象数组,`c`参数是比较器,用于指定排序的规则。 比较器是一个接口,通常使用Java 8中的lambda表达式来实现。比较器应该返回一个整数值,表示两个对象的大小关系。如果返回值小于0,则表示第一个对象小于第二个对象;如果返回值等于0,则表示两个对象相等;如果返回值大于0,则表示第一个对象大于第二个对象。 下面是一个示例,演示如何使用`Arrays.sort()`方法对对象数组进行排序: ```java class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public class ObjectArraySortDemo { public static void main(String[] args) { Person[] persons = { new Person("Alice", 25), new Person("Bob", 30), new Person("Charlie", 20) }; // 按年龄升序排序 Arrays.sort(persons, Comparator.comparingInt(person -> person.age)); // 输出排序后的结果 System.out.println(Arrays.toString(persons)); } } ``` 输出结果为: ``` [Person{name='Charlie', age=20}, Person{name='Alice', age=25}, Person{name='Bob', age=30}] ``` 在上面的示例中,我们创建了一个`Person`类,并创建了一个包含三个`Person`对象的数组。然后我们使用`Arrays.sort()`方法对数组进行排序,排序的依据是`Person`对象的`age`属性,使用了`Comparator.comparingInt()`方法来指定按照`age`属性进行排序。最后,我们输出排序后的结果。 除了上面的示例中使用的`Comparator.comparingInt()`方法,还有其他的比较器可以使用,例如: - `Comparator.comparing()`:使用对象的某个属性进行排序; - `Comparator.reverseOrder()`:逆序排列; - `Comparator.naturalOrder()`:自然排序,用于实现`Comparable`接口的类; - 自定义比较器,实现`Comparator`接口的`compare()`方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

心寒丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值