生活中处处充满了排序:
a.军训站队列时,需同学们按照身高从高到矮排列
b.期末考试,会给全年级同学排名次,让同学们通过此数据进一步地去评价自己,总结学期得失;
c.评选国家奖学金时,会根据候选人的评选分的高低来确立获奖名单;
接下来,让我们一起走进排序的世界,去感受其中的运转方式…
排序的概念
定义
一串序列S = {r1,r2,r3,r4…}(每个元素中含有n个记录),确立排序因素(即:关键字),对关键字进行排序,使序列顺序发生改变,称为排序。
排序的稳定性
假设 k1=k2,未排序之前序列 r1<r2,若排序后仍然r1<r2,则称所用的排序方法是稳定的;反之,则所用的排序方法是不稳定的。
排序的分类
- 内排序:所有的排序操作在内存中进行
- 外排序:所存数据量过于庞大,不能同时存放在内存中进行,需要内存,外存,硬盘之间多次进行数据的交换才能进行。
影响排序算法性能的几个要素
- 时间性能(比较次数,移动次数)
- 辅助空间
- 算法的复杂性
主要排序算法:
- 冒泡排序
- 选择排序
- 直接插入排序
- 希尔排序
- 堆排序
- 归并排序
- 快速排序
- (以后有新的再来慢慢补充…)
冒泡排序
1.思路:两两相邻的记录的关键字,如果反序则交换,直到没有反序的记录为止。
2.经典代码
两两相邻,比较交换,比较交换…
void BubbleSort(int a[], int n)
{
int i, j;
for(i=0;i<n-1;i++)
for(j=0;j<n-i-1;j++);
{
if(a[j]>a[j+1])
swap(a[j],a[j+1]);
}
}
优化方案一(优化外层循环):设置标志变量flag
若某次比较过程未发生交换,则证明序列已完成排序工作,不必继续遍历,比较,排序。
void BubbleSort_2(int a[], int n)
{
int i, j, flag=1;//flag=1时,已发生交换过程
for(i=0; i<n-1&&flag!=0; i++)
{
flag = 0;
for(j=0;j<n-1-i;j++)
{
if(a[j]<a[j+1])
{
swap(a[j],a[j+1]);
flag = 1;
}
}
}
}
优化方案二(优化内层循环):记录最后一次发生交换的位置
内层循环中,设最后一次交换位置为m,则序列1~m-1为无序,m-n为有序(此段内不用再次比较)
void BubbleSort_3(int a[], int n)
{
int i=n-1, j, last_exchange;
while(i)
{
last_exchange = 0;//未发生交换
for(j=0;j<i;j++)
{
if(a[j]<a[j+1])
{
last_exchange = j;
swap(a[j],a[j+1]);
}
i = last_exchange;
}
}
}
貌似还有一种优化:鸡尾酒排序
等以后再来总结吧
2019.5.11 20:22