冒泡排序 0(N^2)
执行非常慢,概念上最简单。最大的会一直被交换,冒泡上来
|
|
选择排序0(N^2)
比较所有的数据项,取出最小值,放左边。比较剩下的数据,取最小,放最左。。。。
内层循环中,每一个in的新位置,数据项a[in]和a[min]比较,如果a[in]更小,则min被赋值为in的值,这里只是下标,没交换。到一次内层循环结束,再交换数据项。这样,最小数据项就会一直被放在左边。
|
|
插入排序 N*(N-1)/2 /2
假设左边部分已经排序好了,从某个位置(比如10)开始无序,将10赋值给一临时值,然后和前面的数据比较,如果9位置比10大,就9右移一位,继续和8比较。。。直到到数据的最左边或找到比10位置数据小的某数据,放在它的右边,10位置的数据就排好了。
在大多数情况下,插入算法仍然需要0(N^2)的时间,但比冒泡快一倍,比选择排序也还要快一点。经常被用在较复杂的排序算法的最后阶段,例如快速排序。
|
|
归并排序O(N logN)
只要O(N logN),而冒泡排序,选择排序,插入排序都要用O(N N);.
归并排序的思想是:将一个数组分成两半,然后分别排序,然后将数组的两半合并,合并的时候需要比较大小(合并的时候还要考虑两小数组还有没有数据,即有可能一边有,另一边没有)。至于如何排序1/2半的数组,当然是再分成两个1/4数组,再排序。。。直到分割的小数组只有1个数据项,不用排序了。这是用到递归的思想
归并排序的缺点,需要在存储器中有另一个大小等于被排序的数据项数目的空间,用来复制分割出来的小数组。
归并算法的效率由来:需要复制log2N层(分子数组),每一个层都是N个数据,所以是NxlogN.
|
|
希尔排序
希尔排序基于插入排序,但增加了一个新的特性,大大地提高了插入排序的执行效率。(希尔是个人名。。。)
改进的地方:插入算法中,如果一个数据比较小而居于最右边,那么它需要一个一个地移动所有中间的数据项,效率比较低。
希尔排序通过加入插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项能大跨度地移动。当这些数据项排过一趟序后,减小数据项的间隔。再进行排序,依次进行下去。间隔被称为增量,用h表示.
进行过几次增量排序后,所有的元素离它再最终有序序列中的位置相差不大,数组达到”基本有序”,这时再来插入排序,移动量非常小。
当h值很大的时候,数据项每一趟排序需要移动元素的个数很少,但数据项移动的距离很长,这是非常有效率的。当h减少时,每一趟排序需要移动的元素的个数增多,但是此时数据项已经接近于它们排序后最终的位置,这对于插入排序可以更有效率。
其中,h = h x 3 +1, h = (h -1) / 3,是经验值。
|
|
划分算法
划分是快速排序的根本机制,但是划分本身也是一个有用的操作,这里单讲划分的算法。
划分数据就是把数据分为两组,使所有关键字大于特定值的数据项在一组,使所有关键字小于特定值的数据项在另一组。
划分算法由两个指针开始工作,两个指针分别指向数组的两头。在左边的指针,leftPtr,向右移动,而在右边的指针,rightPtr,向左移动。
实际上,leftPtr初始化时是在第一个数据项的左边一位(-1),rightPtr是在最后一个数据项的右边一位(size),这是因为在工作之前,它们都要分别的加一和减一。
停止和交换:当leftPtr遇到比枢纽(特定值,划分值)小的数据项时,它继续右移,因为这个数据项的位置已经处在数组的正确一边了。但是,当遇到比枢纽大的数据项时,它就停下来。类似的,当rightPtr遇到小于枢纽的数据项时,它也停下来。两个内层的while循环,控制这个扫面过程,当两个都停下来时,要么指针到头要么遇到错误的数据(大小比较不对),做交换(更换位置,正确排列了)。
当两个指针最终相遇的时候,划分过程结束,并且推出这个外层的while循环。
|
|
快速排序
最流行的排序算法,时间复杂度为O(N*logN)。虽然不觉得这种行为好,但有的公司喜欢笔试时让人手写快排(一些开发者如是说)。
原理是:把一个数组划分为两个子数组,这里用到划分算法,左子数组的数据项都小于右子数组的数据项,然后递归地调用自身为每个子数组进行快速排序来实现,最后使用插入排序。
在这个算法中划分的关键值(枢纽)的选择非常重要。
最初思想,选用数组最右边的值为pivot,进行一次划分,划分的结果就是left->mid-1, mid->right-1, right(这个位置的值是pivot),三部分,然后交换mid和right的值(划分算法的leftPtr在停止时会停在mid位置),这样pivot就到中间,而小于pivot的值全在左边,大于的值全在右边,数组的排序不受影响。
下面的排序从left到pivot-1,pivot+到right。中间项不参与划分。
|
|
作者 夏目
2016 年 12月 05日