从杂乱到有序并不简单--排序算法
排序,生活中的平常事,在众多无序个体中,选择一种标准,如从大到小,从高到矮,从多到少进行排列,使之成为一个有序有规律的序列,这就是排序!
排序对少数个体而言,是一件容易的事,如两个个体,比较一次就可以决定,三个个体则在比较三次才能确定,当个体数目大时,排序并不容易。好多排序方法复杂度上是效率 O(n²)。
真实地讲,从杂乱到有序并不简单。本文来谈谈排序算法。
正因为排序算法不简单,所有前人为我们找到了好多算法,这些排序算法,各有千秋,难易不同,当然效率也不同。
据我所了解,大约有十来种排序算法。它们是
- 冒泡(Bubble)排序——相邻交换
- 选择排序——每次最小/大排在相应的位置
- 插入排序——将下一个插入已排好的序列中
- 希而/尔(Shell)排序——缩小增量
- 归并排序
- 快速排序
- 堆排序
- 拓扑排序
- 锦标赛排序
- 基数排序
一般地,考虑一个算法的好坏,主要从下三个方面来考虑:
(1)执行时间
时间复杂度,主要考虑执行主要功能运算要运算的次数。
(2)存储空间
运算时需要占用的存储空间。
(3)编程工作量
在排序数据不多时,(1)(2)因素差别不大,这时主要考虑因素3了。对于大量的数据,时间复杂度是算法首要考虑的因素,因为排序算法时的效率是数据量的平方O(n²)。
下面将分别介绍各种排序算法。
一、冒泡(Bubble)排序
冒泡排序,是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,重复地进行直到没有再需要交换。这个算法的名字是一种形象的说法,越小的元素会经由交换慢慢“浮”到数列的顶端,犹如水中的气泡慢慢浮起来而冒出水面。
冒泡排序算法的如下:
比较相邻的元素。如果第一个比第二个大或小,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
以下面数据为例,说明排序过程:
初始关键字 [9 8 5 4 2 0]
第一轮: [9 8 5 4 2 0]
第1次排序后[8 9 5 4 2 0]
第2次排序后[8 5 9 4 2 0]
第3次排序后[8 5 4 9 2 0]
第4次排序后[8 5 4 2 9 0]
第5次排序后[8 5 4 2 0 9]
第二轮: [8 5 4 2 0 9]
第1次排序后[5 8 4 2 0 9]
第2次排序后[5 4 8 2 0 9]
第3次排序后[5 4 2 8 0 9]
第4次排序后[5 4 2 0 8 9]
第三轮: [5 4 2 0 8 9]
第1次排序后[4 5 2 0 8 9]
第2次排序后[4 2 5 0 8 9]
第3次排序后[4 2 0 5 8 9]
第四轮: [4 2 0 5 8 9]
第1次排序后[2 4 0 5 8 9]
第2次排序后[2 0 4 5 8 9]
第五轮: [2 0 4 5 8 9]
第1次排序后[0 2 4 5 8 9]
总共运算次数:5+4+3+2+1=15
算法伪码:
for(int i=1;i<n;i++)
for(intj=0;i<n-i;j++)
if(a[j]>a[j+1]) //比较相邻元素
{ int temp;
temp=a[j]; //交换相邻元素
a[j]=a[j+1];
a[j+1]=temp;
}
上例数据有些特殊,原来数序列是从大到小的,是好让大家看到数据移动过程,大家看到9了吗,一直从左向右移动,如果将数列倒置,就犹如气泡上浮,这正是气泡法的由来。所以,冒泡排序算法是一种较容易理解的算法,也是初学者一般都要求掌握的算法,其它几种算法将会一一介绍。