数据结构与算法系列十三(选择排序)

143 阅读4分钟

上一篇:数据结构与算法系列十二(插入排序) 中,我们详细分析了插入排序的核心思想,和代码实现。插入排序的核心思想很巧妙:它是将待排序序列,分为有序区间,和无序区间,循环遍历无序区间,每一次将无序区间中的第一个元素插入到有序区间的合适位置,每一次插入都要始终保证有序区间有序。

你需要对插入排序的核心思想再仔细琢磨一下,因为我们今天的主角:选择排序,它的核心思想与插入排序类似。

#考考你:
1.你知道选择排序的核心思想吗?
2.你能用java代码实现选择排序吗?
3.你知道实际开发中,为什么插入排序,比选择排序更好吗?

案例

选择排序核心思想

假设有一个待排序序列:[4, 5, 6, 3, 2, 1]。我们需要按照升序进行排序,排序后的序列是这 样的:[1, 2, 3, 4, 5, 6]。

如何通过选择排序实现呢?

选择排序核心思想:

将待排序序列,分成两个区间:有序区间无序区间。一开始假定有序区间元素个数:0无序区间元素个数:n。循环遍历无序区间,每一次从无序区间中,选择最小的一个元素,插入到有序区间的末尾

这里的关键词有:

1.待排序序列,分成:有序区间、无序区间
2.最开始,假定有序区间元素个数:0,无序区间元素个数:n
3.每次循环遍历无序区间,选择最小元素,插入到有序区间末尾,如下图:

image.png

选择排序代码实现

排序代码

/**
* 选择排序
* @param array:待排序数组
* @param n:待排序数组大小
*/
public static void sort(Integer [] array,int n) {
   // 如果排序数组规模小于等于1,直接返回
   if (n <= 1) {
       return;
   }

   // 将待排序数组,分为:有序区间、无序区间
   // 一开始,假设整个序列都无序,那么有序区间的元素个数是:0
   // 无序区间的元素个数是:n
   // 每次从无序区间中,选择最小元素
   // 插入有序区间末尾:n个元素,n次选择
   for(int i = 0; i < n; i++){

      // 从无序区间第一个位置开始查找:最小元素位置
      int min = i;
      for(int j = i+1; j < n; j++){
        // 比较大小,设定新的最小元素位置标记
        if(array[min] > array[j]){
             min = j;
         }
      }

     // 找到新的最小元素位置后,进行数据交换
    System.out.println("第【"+(i+1)+"】次选择,最小元素是:"+array[min]);
    int tmp = array[i];
    array[i] = array[min];
    array[min] = tmp;

   }

}

测试代码

/**
 * 选择排序:
 * 1.时间复杂度:
 *      O(n^2)
 *  2.空间复杂度:
 *      O(1)是原地排序算法
 * 3.算法稳定性:
 *     不是稳定排序算法
 */
public static void main(String[] args) {
   // 初始化测试数组
   Integer[] array = {4,5,6,3,2,1};
   // 排序前
   System.out.println("1.排序前数组:" + Arrays.deepToString(array));

   // 排序
   System.out.println("2.开始排序-------------------------------start");
   sort(array,array.length);

   // 排序后
   System.out.println("3.排序后数组:" + Arrays.deepToString(array));
 }

image.png

讨论分享

#考考你答案:
1.你知道选择排序的核心思想吗?
  1.1.将待排序序列,分成:有序区间、无序区间
  1.2.最开始,有序区间元素个数:0,无序区间元素个数:n
  1.3.循环遍历无序区间,每次选择最小元素,插入有序区间末尾
  
2.你能用java代码实现选择排序吗?
  2.1.参考【3.2】节代码实现
  
3.你知道实际开发中,为什么插入排序,比选择排序更好吗?
  3.1.我们在排序算法概述中说过,衡量一个排序算法的优劣,
  有三个因素:时间复杂度、空间复杂度、是否稳定
  3.2.插入排序与选择排序,它们的时间复杂度都是:O(n^2)
  3.3.插入排序与选择排序,它们的空间复杂度都是:O(1)
  3.3.插入排序,是稳定的排序算法
  
  3.4.【注意】:选择排序,不是稳定排序算法
  3.5.假设有一个待排序序列:int a[]={4,5,6,4,3,2,1}
  3.6.待排序序列中,有重复元素:a[0]=4,a[3]=4
  3.7.第一轮选择排序,选择最小元素:a[6]=1
  3.8.将a[0]=4,a[6]=1进行交换
  
  3.9.【注意】:第一轮选择排序后,重复元素4的顺序发生了改变
  3.10.待排序序列变成:a[]={1,5,6,4,3,2,4}
  3.11.此时重复元素:a[3]=4,a[6]=4
  3.12.a[3]还是原来的a[3],a[6]是原来的a[0]
  
  3.13.我们说稳定排序算法,是指待排序序列中重复元素,
  排序前的顺序,与排序后的顺序保持不变
  3.14.可见选择排序,不符合稳定排序算法的定义
  3.15.关于选择排序,不是稳定排序算法的分析,你可以结合我们前面的图来理解