第一次写博客,很慢很慢很不适应,但是感觉不错,可以记录自己的学习成果,也算是变相监督自己学习吧。首次尝试,也不敢整高大上的内容,先从最简单的排序算法开始吧。
铁甲依然在。 --九州
在各种算法问题中,排序算法是最基本的问题,貌似很多面试笔试都要问道这个=-=。排序(Sort)是指按照一定的规则(一般是递增或者递减)将数据进行排列。
常见的排序算法有:交换(冒泡排序、快速排序),选择(选择排序、堆排序),插入(插入排序,shell排序),合并。
此外还有多路归并排序(数据量较大时,由于计算机内存的限制,往往不能直接将数据读入内存进行操作。这次采用多路归并的策略,将文件划分为几个能够读入内存的小部分,分别读入内存,之后将结果进行归并)。
交换:冒泡排序、快速排序
选择:选择排序、堆排序
插入:插入排序、shell排序
1.冒泡排序(Bubble Sort)
冒泡排序法是所有排序算法中最简单、最基本的一种。其思想就是交换排序,通过交换相邻的来达到排序的目的。动态的去想象这个过程,数据会一层一层的向上冒,盖因此得名焉。
冒泡排序法通过多次比较和交换来实现排序,排序的流程如下(以增序为例):
(1)对数组中的各数据,依次比较相邻两个元素的大小。
(2)如果前者大于后者,则交换;经过第一轮的多次排序后,便可把最小的数排好。
(3)再用同样的方法对剩下的数进行排序,迭代至所有数排序完毕。
为了更清晰的表达冒泡排序法的执行过程,在下举一个例子。对于5个整型数据118、101、105、127、112组成的一个无序数组进行从小到大的排序。
初始数组:118 101 105 127 112
一次比较:101 118 105 127 112
首先进行第一次比较,118大于101,故交换。
二次比较:101 105 118 127 112
进行第二次比较,118同样大于105,仍然交换。
三次比较:101 105 118 127 112
进行第三次比较,118小于127,故不交换。
四次比较:101 105 118 112 127
进行第四次比较:交换112 和127
以上为第一次排序的过程,经过(数组元素个数-1)次比较的过程,实际上找出了整个数组里面的最大值,并将其放置在数组的最后一个位置,即排好了数组的最大值。依次迭代,可以相继排好数组的次大值,次次大值,直至所有元素排序完毕。
值得一提的是,上述过程如果从后往前遍历比较,那么第一次排序排好的是数组的最小值。
2.选择排序法(Selection Sort)
选择排序法也是比较简单的排序算法,思路是在每一步中选取最小值来重新排列,从而达到排序的目的。
选择排序法通过选择和交换来进行排序,其排序流程如下:
(1)首先从原始数组中找到最小的元素,将其和第一个位置的元素交换。
(2)从剩下的n-1个元素中找到最小的元素,将其和第二个位置的元素交换。
(3)重复上述过程,直至所有元素排序完毕。
该算法其实就是封装了多个求最值得过程来进行排序。
3.插入排序法(Insertion Sort)
插入排序发通过对未排序的数据执行逐个插入至合适的位置而完成排序的工作。
插入排序法通过比较和插入来实现排序,其排序的流程如下:
(1)首先对数组的前两个元素进行从小到大的排序。
(2)接着对第3个元素与已经排好序的两个元素比较,并插入到合适的位置。
(3)然后,将第四个元素插入到已经排好序的前3个数据中。
(4)不断重复上述过程,直到把最后一个和元素插入到一个合适的位置。
同样,在下还是举个例子来说明插入排序的执行过程。对于5个整型数据118、101、105、127、12组成的一个无序数组进行从小到大的排序。
初始数组:118 101 105 127 112
一次插入:101 118 105 127 112
第一次插入,将前面两个元素按照从小到大排序。可以理解为将第二个元素插到第一个元素中。
二次插入:101 105 118 127 112
第二次插入,将第三个元素插入到已经排号序的前面两个元素中,至此前面三个元素以及排号序。
三次插入:101 105 118 127 112
第三次插入,排好前面四个元素。
四次插入:101 105 118 112 127
第四次插入,完成整个数组的排序。
针对插入排序,如果原始数据是基本有序的,效率较高。但是如果数据本身很不规则,则需要移动大量的数据,其排序效率也不是很好。
4.shell排序算法
前面介绍的几种算法,虽然思路比较直观,容易理解,但是效率不高。对于大量数据需要排序的时候,我们往往需要效率更高的算法,shell算法算一个。
shell算法的思想来自于插入算法,其又称为希尔排序或者缩小增量的排序。排序流程如下:
(1) 将有n个元素的数组分为n/2个数对,第1个元素和第n/2+1个元素为一对。。。。。依次类推,第i个元素和第n/2+i个元素为一对。
(2) 一次循环使每一个数队排好顺序。
(3) 然后,再变为n/4个序列,再次排序。
(4) 不断重复上述过程,随着序列减少至一个,也就完成了整个数组的排序。
下面用例子来具体说明shell算法的执行过程。
原始数组:127 118 105 101 112 100
一次排序:101 112 110 127 118 105
第一次排序,首先将数组分为6/2=3个序列,分别是(127,101),(118,112),(105,100)。并对各个序列进行排序操作。
二次排序:100 101 105 112 118 127
第二次排序,将数组分为6/4=1(取整),此时逐个对数据比较,按照插入排序的算法对这个序列进行排序。
我们已经知道,如果数据本身就是基本有序的,那么插入排序的效率会较高。shell排序法就是不断提高数组的有序性,配合插入算法提高排序的效率。