1.动画展示

选择.gif

2.思路分析

  1. 第一个跟后面的所有数相比,如果小于(或大于)第一个数的时候,暂存较小数的下标,第一趟结束后,将第一个数,与暂存的那个最小数进行交换,第一个数就是最小(或最大的数)
  2. 下标移到第二位,第二个数跟后面的所有数相比,一趟下来,确定第二小(或第二大)的数

重复以上步骤
直到指针移到倒数第二位,确定倒数第二小(或倒数第二大)的数,那么最后一位也就确定了,排序完成。
image.png
image.png

3.复杂度分析

  1. 不管原始数组是否有序,时间复杂度都是O(n^2),

因为每一个数都要与其他数比较一次,(n-1)^2次,分解:n^2-2n+1, 去掉低次幂和常数,剩下n^2,所以最后的时间复杂度是O(n^2)。

  1. 空间复杂度是O(1),因为只定义了两个辅助变量,与n的大小无关,所以空间复杂度为O(1)。

    4.代码实现

    最近看的,较容易理解
    1. public static void Select(int[] arr){
    2. //跟冒泡一样第一轮:同样只需要比较长度-1次
    3. for (int i = 0; i < arr.length-1; i++) {
    4. //i代表每轮选择最小元素要交换到的目标索引
    5. int s = i;//代表最小元素的索引,
    6. // 一开始认定一开始为i,后面找打更小的再更新s
    7. for (int j = i+1; j <arr.length ; j++) {
    8. if (arr[j]<arr[s]){
    9. s=j;
    10. }
    11. }
    12. if (s!=i){
    13. swap(arr,s,i);
    14. }
    15. System.out.println(Arrays.toString(arr));
    16. }
    17. }
  1. public class SelectSort {
  2. public static void main(String[] args) {
  3. int arr[] = {6,7,9,5,2};
  4. System.out.println("排序前");
  5. System.out.println(Arrays.toString(arr));
  6. selectSort(arr);
  7. System.out.println("排序后");
  8. System.out.println(Arrays.toString(arr));
  9. }
  10. public static void selectSort(int[] arr){
  11. /**
  12. * 思路:假设第一个值为最小值,每一轮排序,最小值后面的数与该轮最小值的数进行比较,
  13. * 如果后面有比这个值还要小,则改变这个设定的最小值为这个值,并交换两个值的索引位置,
  14. 进而交换两个值的位置。
  15. */
  16. for (int i = 0; i <arr.length ; i++) {//arr[i]为每轮设定的最小值
  17. int minIndex = i; //假设第一个值为最小值i
  18. int min = arr[i];
  19. for (int j = i + 1; j <arr.length ; j++) {
  20. if (min > arr[j]){
  21. min = arr[j]; //重置最小值
  22. minIndex = j ; //重置最小值的索引
  23. }
  24. }
  25. if (minIndex != i) { //优化
  26. arr[minIndex] = arr[i]; //交换两个值
  27. arr[i] = min;
  28. }
  29. }
  30. }
  31. }

推导过程

  1. //使用逐步推导的方式来,讲解选择排序
  2. //第1轮
  3. //原始的数组 : 101, 34, 119, 1
  4. //第一轮排序 : 1, 34, 119, 101
  5. //算法 先简单--》 做复杂, 就是可以把一个复杂的算法,拆分成简单的问题-》逐步解决
  6. //第1轮
  7. int minIndex = 0;
  8. int min = arr[0];
  9. for(int j = 0 + 1; j < arr.length; j++) {
  10. if (min > arr[j]) { //说明假定的最小值,并不是最小
  11. min = arr[j]; //重置min
  12. minIndex = j; //重置minIndex
  13. }
  14. }
  15. //将最小值,放在arr[0], 即交换
  16. if(minIndex != 0) {
  17. arr[minIndex] = arr[0];
  18. arr[0] = min;
  19. }
  20. System.out.println("第1轮后~~");
  21. System.out.println(Arrays.toString(arr));// 1, 34, 119, 101
  22. //第2轮
  23. minIndex = 1;
  24. min = arr[1];
  25. for (int j = 1 + 1; j < arr.length; j++) {
  26. if (min > arr[j]) { // 说明假定的最小值,并不是最小
  27. min = arr[j]; // 重置min
  28. minIndex = j; // 重置minIndex
  29. }
  30. }
  31. // 将最小值,放在arr[0], 即交换
  32. if(minIndex != 1) {
  33. arr[minIndex] = arr[1];
  34. arr[1] = min;
  35. }
  36. System.out.println("第2轮后~~");
  37. System.out.println(Arrays.toString(arr));// 1, 34, 119, 101
  38. //第3轮
  39. minIndex = 2;
  40. min = arr[2];
  41. for (int j = 2 + 1; j < arr.length; j++) {
  42. if (min > arr[j]) { // 说明假定的最小值,并不是最小
  43. min = arr[j]; // 重置min
  44. minIndex = j; // 重置minIndex
  45. }
  46. }
  47. // 将最小值,放在arr[0], 即交换
  48. if (minIndex != 2) {
  49. arr[minIndex] = arr[2];
  50. arr[2] = min;
  51. }
  52. System.out.println("第3轮后~~");
  53. System.out.println(Arrays.toString(arr));// 1, 34, 101, 119 */

运行截图
image.png

代码2

  1. public static void selectionSort(int[] array) {
  2. if (array == null || array.length <= 1) {
  3. return;
  4. }
  5. int length = array.length;
  6. for (int i = 0; i < length - 1; i++) {
  7. // 保存最小数的索引
  8. int minIndex = i;
  9. for (int j = i + 1; j < length; j++) {
  10. // 找到最小的数
  11. if (array[j] < array[minIndex]) {
  12. minIndex = j;
  13. }
  14. }
  15. // 交换元素位置
  16. if (i != minIndex) {
  17. swap(array, minIndex, i);
  18. }
  19. }
  20. }
  21. private static void swap(int[] array, int a, int b) {
  22. int temp = array[a];
  23. array[a] = array[b];
  24. array[b] = temp;
  25. }
  26. }

5.选择排序与冒泡排序的比较

  1. 时间负责度都是O(n2)
  2. 空间复杂度都是O(1)
  3. 选择排序是从第一位开始确定最大或最小的数,保证前面的数都是有序的,且都比后面的数小或大;

冒泡排序是从最后一位开始确定最大或最小的数,保证后面的数都是有序的且都大于或小于前面的数。