小言_互联网的博客

排序算法 | 直接选择排序

544人阅读  评论(0)

直接选择排序(Straight Selection Sort)

选择排序的基本思想是:每一趟从待排序的记录中选出关键字最小的记录,顺序放入已排序数列的最后,直到全部记录排序完毕。

直接选择排序是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 即在每一步中选取最小值来重新排列,从而达到排序的目的。(选择+交换)


目录

直接选择排序(Straight Selection Sort)

1、算法描述

2、算法分析

2.1、复杂度分析

2.1.1、时间复杂度

2.1.2、空间复杂度

2.2、算法稳定性

3、算法实现

4、算法示例

5、注意


1、算法描述

基本思想:n个记录的数列的直接选择排序可经过n-1趟直接选择排序得到有序结果

  1. 初始状态:无序区为 a[1..n],有序区为空。

  2. 第 1 趟排序:在无序区 a[1..n]中从左向右遍历,遇到比第 0 个位置小的值 a[k],将它与无序区的第 0 个位置 a[0]交换。直到比较到最后一个元素。使 a[1..i]和 a[2..n]分别变为记录个数增加 1 个的新有序区和记录个数减少 1 个的新无序区。

  3. 第 i 趟排序:第 趟排序开始时,当前有序区和无序区分别为 a[1..i-1]和 a[i..n][1≤i≤n-1]。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第 i 个记录 R[i]交换,使 R[1..i] R[i+1..n]分别变为记录个数增加 1 个的新有序区和记录个数减少 1 个的新无序区。

  4. 这样,n 个记录的数列的直接选择排序可经过 n-1 趟直接选择排序得到有序结果。

简单选择排序的基本思想:选择 + 交换。

  1. 从待排序序列中,找到关键字最小的元素;
  2. 如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
  3. 从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。

因此我们可以发现,简单选择排序也是通过两层循环实现

  1. 第一层循环:依次遍历序列当中的每一个元素
  2. 第二层循环:将遍历得到的当前元素依次与余下的元素进行比较,符合最小元素的条件,则交换

2、算法分析

2.1、复杂度分析

无论数列初始状态怎样,在第 i 趟排序中选出最小关键字的记录,需做 n-i 次比较,因此,总的比较次数为: n(n-1)/2=O(n^2)。

2.1.1、时间复杂度

  • 最好情况O(n^2)
  • 最坏情况O(n^2)
  • 平均情况O(n^2):平均来说直接选择排序算法的时间复杂度为O(n^2)

因而,直接选择排序不适合对于数据量比较大的排序应用

2.1.2、空间复杂度

直接选择排序是一个就地排序,空间复杂度为S(n)=O(1)

2.2、算法稳定性

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

3、算法实现


  
  1. void straightselectionsort(vector<int>&a)
  2. {
  3. for ( int i = 0; i < a.size(); i++)
  4. {
  5. //找出无序队列的最小值
  6. for ( int j = i + 1; j < a.size(); j++)
  7. {
  8. if (a[j] < a[i])
  9. {
  10. swap(a[i], a[j]);
  11. }
  12. }
  13. }
  14. }

4、算法示例


  
  1. #include "stdafx.h"
  2. #include <vector>
  3. #include <iostream>
  4. #include <stack>
  5. #include<time.h>
  6. using namespace std;
  7. void straightselectionsort(vector<int>&a)
  8. {
  9. for ( int i = 0; i < a.size(); i++)
  10. {
  11. //找出无序队列的最小值
  12. for ( int j = i + 1; j < a.size(); j++)
  13. {
  14. if (a[j] < a[i])
  15. {
  16. //输出
  17. cout << '\n' << "交换的位置是: " << '\t' << i << " <-----> " << j << '\t' << "交换的值是: " << a[i] << " <-----> " << a[j] << '\n';
  18. swap(a[i], a[j]);
  19. for ( int i = 0; i < a.size(); i++)
  20. {
  21. cout << a[i] << '\t';
  22. }
  23. cout << '\n';
  24. }
  25. }
  26. }
  27. }
  28. int main()
  29. {
  30. vector< int>a;
  31. cout << '\n' << "原顺序: " << '\n';
  32. a.push_back( 7); a.push_back( 8); a.push_back( 7);
  33. a.push_back( 6); a.push_back( 5); a.push_back( 6);
  34. a.push_back( 7); a.push_back( 8); a.push_back( 9);
  35. for ( int i = 0; i < a.size(); i++)
  36. {
  37. cout << a[i] << '\t';
  38. }
  39. cout << '\n' << '\n';
  40. cout << '\n' << "排序过程: " << '\n';
  41. straightselectionsort(a);
  42. cout << '\n' << "希尔排序: " << '\n';
  43. for ( int i = 0; i < a.size(); i++)
  44. {
  45. cout << a[i] << '\t';
  46. }
  47. cout << '\n';
  48. return 0;
  49. }

5、注意

 


转载:https://blog.csdn.net/qq_35683407/article/details/105926789
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场