选择排序(多方式)

简介: 选择排序(多方式)



直接选择排序

基本思想:给定一个待排序的数组或列表,简单选择排序通过不断选择最小(或最大)元素,并将其放置到已排好序部分的末尾,从而逐步构建有序序列

实现步骤:1、记录无序数组的首尾元素坐标begin和end,同时利用maxi和mini记录每次比较过程中最大数和最小数的下标(只是下标而不是具体的数字,在一轮比较完成后才会进行数字的交换,而且由于是要选出每次比较的最大/小值,所以当一个数字的大小在下标为maxi和mini的元素之间时,maxi或mini的值不会改变),二者的初始值都是数组首元素下标0(这样从第一次开始比较时就能将maxi或者mini分开便于后续的比较)

2、我们在这里规定比较是“新元素(初始新元素为数组首元素的下一个元素,所以要begin+1)与元素下标为maxi和mini之间的关系,第一次比较是“新数字89”与元素下标为maxi和mini之间的关系,89大于5,所以此时mini不变,但是maxi发生改变,它此时记录新的最大值下标(0->1)

3、第二次比较,“新数字3”与元素下标为maxi和mini之间的关系,3小于5,所以此时mini改变,记录新的最小值下标(0->2)

4、 第三次比较,“新数字6”与元素下标为maxi和mini之间的关系,6大于3小于89,不算最大也不算最小,所以此时mini和maxi均不发生改变

5、 第四次比较,“新数字0”与元素下标为maxi和mini之间的关系,0小于3,所以此时mini改变,记录新的最小值下标(2->4)

5、 第五次比较,“新数字48”与元素下标为maxi和mini之间的关系,48大于0小于89,不算最大也不算最小,所以此时mini和maxi均不发生改变

6、 第六比较,“新数字12”与元素下标为maxi和mini之间的关系,12大于0小于89,不算最大也不算最小,所以此时mini和maxi均不发生改变

7、 第七次比较,“新数字2”与元素下标为maxi和mini之间的关系,2大于0小于89,不算最大也不算最小,所以此时mini和maxi均不发生改变

8、至此第一轮比较结束,此时将下标为maxi和mini元素分别与数组首尾元素交换位置

9、此外,为了避免由于代表最大值下标的maxi与begin相等,即在交换完a[mini]与a[begin]之后,a[mini]的位置被最大值覆盖,所以我们要在交换完后更新maxi的位置,将此时mini赋值给maxi,然后再去交换a[maxi]与a[end](不需要考虑mini与maxi重合的问题,因为每次每次循环开始是它们都会被重置)

10、最后外面再多套一层while循环,保证不断缩小比较的范围,当begin与end相等时,整个序列就会变为有序序列:

//简单选择排序
void SelectSort(int* a, int n)
{
  int begin = 0, end = n - 1;
  while (begin < end)
  {
    int mini = begin, maxi = begin;
    for (int i = begin + 1; i <= end; ++i)
    {
      if (a[i] < a[mini])
      {
        mini = i;
      }
      if (a[i] > a[maxi])
      {
        maxi = i;
      }
    }
    Swap(&a[begin], &a[mini]);
    if (maxi == begin)
    {
      maxi = mini;
    }
    Swap(&a[end], &a[maxi]);
    ++begin;
    --end;
  }
}

11、如果你觉得这种方法很难理解,那还是用之前的常见的简单选择排序吧:

void selectionSort(int arr[], int n) {
    int i, j, minIndex, temp;
    for (i = 0; i < n-1; i++) {
        minIndex = i;
        // 在剩余未排序部分找到最小元素的索引
        for (j = i+1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 将找到的最小元素与当前位置交换
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}

关于它的解释等有空了我会补上😭

时空复杂度

最坏时间复杂度:O(N^2)一共需要进行 n-1 轮比较和交换操作。每一轮中,需要在剩余未排序的元素中找到最小/大的元素,并将其与当前位置进行交换,(n-1) + (n-2) + ... + 1 = (n^2 - n)/2

最好时间复杂度:O(N^2)(无论输入数据的初始顺序如何,简单选择排序都需要进行 n-1 轮比较和交换操作。在每一轮中,需要找到剩余未排序部分中的最小(或最大)元素,并将其与当前位置进行交换)

空间复杂度:O(1)

简单选择排序的特性

  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  2. 稳定性:不稳定

堆排序

堆的相关内容放在这里了:http://t.csdnimg.cn/XO9Qh

时空复杂度

最坏时间复杂度:O(N*logN)(我们将它们放在了链接中)

最好时间复杂度:O(N*logN)(输入序列已经是一个完全有序的大顶堆或小顶堆时(即满足所有父节点都比子节点大或小),不需要进行任何交换操作。但仍然需要对每个非叶子节点执行一次向下调整操作以保持树形结构性质)

空间复杂度:O(1)

堆排序的特性总结

  1. 堆排序使用堆来选数,效率就高了很多
  2. 稳定性:不稳定

~over~

相关文章
|
1月前
|
搜索推荐
插入排序算法的讲解和代码
【10月更文挑战第12天】插入排序是一种基础的排序算法,理解和掌握它对于学习其他排序算法以及数据结构都具有重要意义。你可以通过实际操作和分析,进一步深入了解插入排序的特点和应用场景,以便在实际编程中更好地运用它。
|
6月前
|
算法
桶排序(简化版)与冒泡排序
桶排序(简化版)与冒泡排序
38 0
|
6月前
|
算法 前端开发 搜索推荐
前端算法之选择排序
前端算法之选择排序
38 0
|
存储 算法 搜索推荐
数据结构各内部排序算法总结对比及动图演示(插入排序、冒泡和快速排序、选择排序、堆排序、归并排序和基数排序等)2
数据结构各内部排序算法总结对比及动图演示(插入排序、冒泡和快速排序、选择排序、堆排序、归并排序和基数排序等)2
255 0
|
6月前
|
搜索推荐 算法
常见排序算法以及冒泡排序的基础使用方法
常见排序算法以及冒泡排序的基础使用方法
43 0
|
6月前
|
人工智能 供应链 搜索推荐
①归并排序、快速排序 、堆排序、计数排序[算法、代码模板、面试题]
①归并排序、快速排序 、堆排序、计数排序[算法、代码模板、面试题]
91 0
|
算法 C语言
冒泡排序 - 【利用冒泡排序模拟实现快速排序的功能】
冒泡排序 - 【利用冒泡排序模拟实现快速排序的功能】
|
存储 算法 搜索推荐
数据结构各内部排序算法总结对比及动图演示(插入排序、冒泡和快速排序、选择排序、堆排序、归并排序和基数排序等)1
数据结构各内部排序算法总结对比及动图演示(插入排序、冒泡和快速排序、选择排序、堆排序、归并排序和基数排序等)1
197 0
|
算法 搜索推荐 C语言
用或不用大O来优化代码(选择排序)
用或不用大O来优化代码(选择排序)
87 0
|
存储 编解码 移动开发
【算法】直接选择排序解析
直接选择排序是指每次都从剩余数据中选出最大或者最小的,将其排在已经排好的有序表后面。
223 0
【算法】直接选择排序解析