专题 排序的基本原理
概念解释
前言
OI竞赛中常用的排序算法共有以下几种,我们分为两类:
- 基于比较;
- 基于计数。
我们这篇文章重点讨论排序的逻辑实现以及代码的实现细节。
特别注意
- 本文中使用的数组下标默认从1开始;
- 本文中默认排序是进行升序排序操作。
算法分析
1.冒泡排序
核心思想
基于比较,一句话总结:
小数上浮,或者大数下沉。无非起起伏伏。
笔者给出算法步骤:
- 轮换 \(n-1\) 次,进行这么多次的交换;
- 在每一次交换中,看看两个指针对应的数组元素是否需要交换,若是,则进行交换。
参考代码
for(int i=1;i<=n-1;i++)
{
flag=true;
for(int j=1;i+j<=n;j++)
if(a[j]>a[j+1])
{
a[0]=a[j];//a[0]作为临时变量
a[j]=a[j+1];
a[j+1]=a[0];
flag=false;
}
if(!flag) break;
}
细节研讨
上面的代码中有着一个优化,就是flag标记。这个是由于。每一次进行交换,如果成功交换,那么就置为false。这样可以提前结束循环,但事实上,带来的只是常数的优化。而且正常竞赛中也没有人会手写排序,何况是这种 \(O(n^{2})\) 的效率低的算法呢。
2.选择排序
核心思想
一句话总结:
基本思想是每一趟从待排序的数据元素中选出最小(或最大) 的一个元素,顺序放在待排序序列的最前面,直到全部数据有序。
事实上,这已经很明显了,很简单的操作:
- 选择一个最大值,(这一步是要遍历整个数组元素的,所以效率低下);
- 插入所求位置(这里依照前文约定,应是最后一个位置)。
参考程序
for(int i=1;i<=n-1;i++)
{
mark=i;
for(int j=i+1;j<=n;j++)
if(a[mark]>a[j]) mark=j;
//增设一个变量,找出最值
if(mark!=i)
{
a[0]=a[mark];
a[mark]=a[i];
a[i]=a[0];
}
}
细节研讨
大体框架与冒泡相同,只是注意一下,循环的范围,这里外一层是控制比较的轮次的。

浙公网安备 33010602011771号