简单选择排序(选择排序)-八大排序三大查找汇总(1)

工作原理:

  每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

稳定性:

  选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。

时间复杂度:

  比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。

  交换次数O(n),最好情况是,已经有序,交换0次;最坏情况下,即待排序记录初始状态是按第一条记录最大,之后的记录从小到大顺序排列,则需要移动记录的次数最多为3(n-1),逆序交换n/2次。

空间复杂度:

  O(1)。简单选择排序需要占用一个临时空间,在交换数值时使用。

比较:

  与插入排序比较:直接选择排序和直接插入排序类似,都将数据分为有序区和无序区,所不同的是直接播放排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有序区,而直接选择排序是从无序区选一个最小的元素直接放到有序区的最后。选择排序是固定位置,找元素。相比于插入排序的固定元素找位置,是两种思维方式。

  与冒泡排序比较:冒泡算法最费时的一是两两比较,二是两两交换,选择排序中交换次数比冒泡排序少多了,n值较小时,选择排序比冒泡排序快。

代码:

 1 void Selectsort(int a[], int n)
 2 {
 3     int i, j, nMinIndex;
 4     for (i = 0; i < n; i++)
 5     {
 6         nMinIndex = i; //找最小元素的位置
 7         for (j = i + 1; j < n; j++)
 8             if (a[j] < a[nMinIndex])
 9                 nMinIndex = j;
10
11         Swap(a[i], a[nMinIndex]); //将这个元素放到无序区的开头
12     }
13 }
14
15 inline void Swap(int &a, int &b)
16 {
17     int c = a;
18     a = b;
19     b = c;
20 }

注意swap交换,若如下不用中间变量,会有一个隐患,如果a, b指向的是同一个数,那么调用Swap1()函数会使这个数为0

1 inline void Swap1(int &a, int &b)
2 {
3     a ^= b;
4     b ^= a;
5     a ^= b;
6 }

这种情况下可以在Swap1()中加个判断,如果二个数据相等就不用交换了

1 inline void Swap1(int &a, int &b)
2 {
3     if (a != b)
4     {
5         a ^= b;
6         b ^= a;
7         a ^= b;
8     }
9 }
时间: 2024-10-19 19:25:08

简单选择排序(选择排序)-八大排序三大查找汇总(1)的相关文章

冒泡排序-八大排序三大查找汇总(3)

基本思想 两两相邻元素之间的比较,如果前者大于后者,则交换: 设数组长度为N. 1.比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换. 2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置. 3.N=N-1,如果N不为0就重复前面二步,否则排序完成. 稳定性 冒泡排序是一种稳定的排序算法 时间复杂度 若文件的初始状态是正序的,一趟扫描即可完成排序.所需的关键字比较次数 和记录移动次数  均达到最小值:  ,  .所以,冒泡排序最好

数据结构之排序算法(八大排序)-(八)

排序算法可以分为稳定排序和不稳定排序.在简单形式化一下,如果A[i] = A[j],A[i]原来在位置前,排序后A[i]还是要在A[j]位置前,这才能叫稳定排序.排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用.基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的.另外,如果排序算法稳定,对基于比较的排序算法而言,元素交换的次数可能会少一些(个人感觉,没有证实). 回到主题,现在分析一下常见的排序

排序算法系列——八大排序算法对比分析

本系列最后一篇,综合分析下前面介绍的八种排序算法的效率,以及各自的适用情况. 下面先看看八种排序算法的时间复杂度表格: 图中八种排序被分成了两组,一组时间复杂度为O(n^2),另一组相对高效些. 下面先对第一组O(n^2)的四种排序算法进行对比,分别取数组长度为100,1000,10000,100000四个数量级,各个元素在0-10000000之间随机获取.下面看下结果的分析. 排序算法 长度=100 长度=1000 长度=10000 长度=100000 直接插入排序 535 2,198 135

堆排序(选择排序)-八大排序三大查找汇总(2)

二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 堆的存储 一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2.它的左右子结点下标分别为2 * i + 1和2 * i + 2.如

归并排序-八大排序三大查找汇总(7)

基本思想 归并排序简单的说就是递归后合并,该算法是分治法(Divide and Conquer)的一个典型应用. 基本思想为:将待排序序列R[0...n-1]看成是n个长度为1的有序序列,两两有序表成对归并,得到n/2个长度为2的有序表:将这些有序序列再次归并,如此反复进行下去,最后得到一个长度为n的有序序列. 综上可知: 归并排序其实要做两件事: (1)“分解”——将序列每次折半划分. (2)“合并”——将划分后的序列段两两合并后排序. 性能 排序类别 排序方法 时间复杂度 空间复杂度 稳定性

希尔排序(插入排序)-八大排序三大查找汇总(5)

基本思想 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序. 稳定性 由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的. 时间复杂度 希尔排序的时间复杂度取决于步长的选择. 平均情况下,

快速排序(交换排序)-八大排序三大查找汇总(6)

基本思想 1.先从数列中取出一个数作为基准数. 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边. 3.再对左右区间重复第二步,直到各区间只有一个数. 性能 时间复杂度:平均情况下的时间复杂度为O(nlogn).最坏情况下时间复杂度为O(n2). 空间复杂度:除去程序运行实现的空间消费(例如递归栈),快速排序算法只需消耗确定数量的空间(即O(1),常数级空间). 稳定性:不稳定的算法 注意 编译器函数库自带的快速排序函数:qsort() 用 法: void qsort

直接插入排序(插入排序)-八大排序三大查找汇总(4)

基本思想 直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止. 直接插入排序是由两层嵌套循环组成的.外层循环标识并决定待比较的数值.内层循环为待比较数值确定其最终位置.直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的.当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环. 时间复杂度 O(

排序 之 冒泡排序 简单选择排序 直接插入排序 希尔排序

排序的基本概念 假设含有n个记录的序列为{r1,r2,--,rn},其相应的关键字分别为{k1,k2,--,kn},需确定1,2,--,n的一种排序p1,p2,--,pn,使其相应的关键字满足kp1≤kp2≤--≤kpn非递减(或非递增)关系,即使得序列称为一个按关键字有序的序列{rp1,rp2,--,rpn},这样的操作就称为排序. 排序的稳定性 假设ki=kj(1≤i≤n,1≤j≤n,i≠j),且在排序前的序列中ri领先于rj(即i<j).如果排序后ri仍领先于rj,则称所用的排序方法是稳定