- 选择排序是不稳定的!!!
- 每一趟在待排序列中选择关键字的最值(最大还是最小看要求),并加入有序子列
1 简单选择排序
1.1 思想
- 这是一个真的很简单的排序算法;
- 每一趟在待排序列中只要最小(最大)的,不论初态,不论技巧;
- 必须 n-1 趟,没得感情,在待排中比较找最值(最大还是最小就看要求);
1.2 算法分析
- 稳定性:不稳定
- 空间复杂度:O(1)
- 与初态是否有关:无关
- 顺序存储 + 链表结构
- 时间复杂度:
最好时间复杂度:O( n^2)
最坏时间复杂度:O( n^2)
平均时间复杂度:O(n^2)
关于时间复杂度:不论初态如何,都会比较 n(n-1)/2 次;对于移动次数,是O(n):可以理解为有序就不需要移动,全是乱糟糟的就要移动 n 次。
1.3 代码
void SelectSort(ElemType A[],int n)
{
for(int i = 1;i < n;i++)//进行n-1趟比较
{
min = i;//记录最小元素的位置,可以不用知道数值
for(int j=i+1; j< n;j++)
{
if(A[j]<A[i])//此时更小的元素出现了,是A[j]
min = j;//更新最小元素的下标
if(min!= i)//交换位置A[min]和A[i]位置
{
A[0]=A[min];A[min]=A[i];A[i]=A[0];
}
}
}
}
2 堆排序
什么是大根堆?什么是小根堆?
大根堆:示意图如下

- 大根堆定义:n个关键字序列 L[1…n]成为堆,当且仅当该序列满足:
L( i ) >= L( 2i ) 且 L( i ) >= L( 2i+1 )
说的更明白点:这棵完全二叉树(堆)的父亲结点树值 >= 他的小孩。。(我的理解是爹比孩子大,最大的爹就是树的根) - 小根堆是反着来的。满足:
L( i ) <= L( 2i ) 且 L( i ) <= L( 2i+1 )
2.1 思想
有点难拿捏。。。
是选择排序的一种改进,属于树形排序法,可以看作是一棵顺序存储的完全二叉树。
过程:
-
建堆:
-
输出堆顶元素;
-
调整,成为新堆;
-
重复B、C,得到一个有序序列。
-
如何实现???让我们来试试叭~(以大根堆为例)
例、关键字序列{42,13,91,23,24,16,5,88},进行升序堆排列
- 建堆:构态+筛选
构态:不管三七二十一先把关键字序列写成二叉树形态
筛选:从(n/2)向下取整处开始检查是不是满足小根堆,至整个数筛选完
【注】筛选法:即从根向叶子结点进行的调整过程。
- 构建二叉树形态

- 筛选(从n/2向下取整开始至根节点,此时从第四个结点调整)

- 筛选(从n/2向下取整开始至根节点,此时从第三个结点调整)

- 筛选(从n/2向下取整开始至根节点,此时从第二个结点调整)

- 筛选(从n/2向下取整开始至根节点,此时从跟结点调整)

此时堆就建好了。
- 输出堆顶元素
最小元素输出之后,堆顶空了,用最后一个叶子节点补上
- 输出堆顶元素重建堆,如何做呢???好问题。
将最后一个叶子节点补上,显然是不满足大根堆的,这个时候自顶向下筛选,至补上的关键字落到应在的位置。
- 重复B、C操作
如下:大致过程
-
建成堆

-
输出堆顶元素 93

-
重建堆

-
输出堆顶元素 88

-
重建堆

-
输出堆顶元素 42

-
重建堆

-
输出堆顶元素 24

-
重建堆

-
输出堆顶元素 23

-
重建堆

-
输出堆顶元素 16

-
重建堆

-
输出堆顶元素 13

2.2 算法分析
- 稳定性:不稳定
- 空间复杂度:O( 1 )
- 与初态是否有关:无关
- 顺序存储
- 时间复杂度:
建堆时间:O ( n ),之后 n-1 次向下调整,调整时间复杂度O( h )
最好时间复杂度:O( n log n)
最坏时间复杂度:O( n log n)
平均时间复杂度:O( n log n) - 插入、删除调整时间与树高有关
一些特点:
- 堆是一棵顺序存储的完全二叉树。
- 像土堆一样,最容易看到的就是它的最值。
2.3 代码
//堆排序
、、、、、、未完待续
本文详细解析了简单选择排序和堆排序的基本思想、算法分析,包括稳定性、空间复杂度、时间复杂度等,并提供了对应的代码示例。通过比较,了解这两种排序算法在效率和应用上的差异。
&spm=1001.2101.3001.5002&articleId=127377958&d=1&t=3&u=07e5e117ee2149218537bc2c1c05b9bc)
2703

被折叠的 条评论
为什么被折叠?



