十大排序—选择排序
Akari[TOC]
参考网站
1.2 选择排序 | 菜鸟教程
数组、链表的基本操作都涉及到排序,排序有很多种,根据情况选择合适的算法即可。
选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
算法步骤
- 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
- 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
- 重复第二步,直到所有元素均排序完毕。
动图演示
理解
就是每一次从未排序的所有元素中,“选出”最小(或最大)的,放在首位,然后递推其余未排序的元素,每一次都选出余下最小的。
例题
ZZULIOJ-Contest 1908-I: 混乱的成绩表
Zero 是一名学习委员,他负责很多有关学习上的任务,今天辅导员给了他一张成绩单,这个成绩单是按学号排序的,但是它是成绩单,应该按成绩排序。Zero 作为一个 acmer,对排序还算了解,但他想考考你,你能完成这个任务吗? |
一个正整数 n,代表成绩单上学生的人数(n <= 2000) |
输出按成绩排名的成绩单,成绩越高,排名越靠前,相同成绩的人 ID 较小的排名在前 |
4 |
4 91 |
结构体代码 选择排序
考察点:结构体、排序
很明显本题让我们对成绩排序,但难点在于每个人的成绩和学号是绑定在一起的,这个时候我们就有两种选择:
- 两个数组,排序时一起交换这两数组的值
- 开一个结构体,排序时交换结构体的值
|
数组代码 选择排序
|
Tip
1. 为什么数组放外面?
将数组定义放在main函数之外更好,因为这样可以使得数组在整个程序中都可见,而不仅仅是在main函数中可见。这样可以使得代码更加清晰易懂。如果数组定义在main函数内部,那么它的作用域就只在main函数内部,而在main函数外部就无法访问该数组。
此外,如果数组定义在main函数内部,那么它的内存分配在栈区内,而栈区的内存是比较小的。因此,如果数组比较大,就会出现爆出的问题,程序无法访问内存就会出错。相对的,如果数组定义在main函数外部,那么它的内存分配在数据区内,数据区的内存较大,所以开数组开在数据区/main函数外面,就不易出现这样的问题。
2. 数组中函数定义为什么只有n?
因为数组在外面定义呀!
整个程序都可以访问,这样函数只需要一个数组长度的参数即可。
3. 为什么设立标志数flag?
因为题目要求成绩越高,排名越靠前,相同成绩的人 ID 较小的排名在前,有两处都需要排序,如果不设立标志数,这两处都需要排序,代码会重复。
设立flag是为了减少重复代码,增强可读性,满足flag就if语句进行交换即可。
4. 为什么结构体里交换只交换成绩而数组里成绩和序号都交换?
因为结构体是捆绑在一起的,学号和成绩一一对应。
而数组里不是,二者没有关系,只交换成绩序号全乱了。
下集预告:冒泡排序(托更bushi)