2012年(106)
分类: C/C++
2012-05-07 16:32:01
第一次上机实验总结:
题目描述:查找最小的k个元素
要求一个序列中最小的k个数,按照惯有的思维方式,先对这个序列从小到大排序,然后输出前面的最小的k个数即可。于是究竟选取什么排序方法是我第一次上机思考很多的,而只有当老师讲解时我才发现我的思维太局限了,题目只要求输出最小的k个数,并没有要求有序,其实k个数都不用有序,又何必对所有的n个数都进行排列呢。
以下简单总结下主要的五种方法:
法一:各种排序方法
法二:用部分排序方法(利用划分的做法,前后都不需要有序)
比快排快,找到k的位置,前面小,后面大。
法三:找最小的k个数中最大的,遍历一遍,比它小的输出。(二分查找有序表;引申:二分查找对无序表查找有技巧,需要递归,查找比排序快得多,不需要交换)
法四:根据特殊情况条件才可以使用。N比较大,先假设k不会很大,前面k个最小,然后把其他数逐段与前k个数比,注意不能是线性结构而是堆结构,增加一个数与其根进行比较,可以适应n非常大,内存放不下,遍历和替换。
法五:如果数据不是特别大而且全是整数,可以开个数组,1-1000个数,生成n个数,是几就往哪个单元去放,生成n个以后只需要从头统计个数即可。
这节课受益匪浅的是让我明白了算法应该有各种思路,各种选择。我应该认真思考分析,多对比,通过实际操作来提高能力以及发散思维。
小知识点:
1. 用常量不用常数的原因:
便于修改,便于阅读(含义易理解)
2. 关于随机数用法:
我们需要一个随机函数,生成不同的随机序列,但由于C语言为伪随机序列,每一次都一样,所以我们需要找到一个保证每回都是不同的随机数的方法:
Srand((unsigned)time(NULL));
注:需加头文件time.h
如果对随机数没有太多的要求,只保证输出整齐,每个数的长度都是一样的,
两位数可以用:
A[i]=rand()%90+10
三位数:
A[i]=rand()%900+100
输出-100到+100的随机数:
A[i]=rand()%201+(-100)
<即|100|+|-100|+1(0)=201>
输出1到365:
A[i]=rand()%365+1
由此,我们找到规律:
A[i]=rand()%a+b
有多少种不同的,a即为多少。B为最小的数。