常见排序算法归纳
排序算法一般分类:
比较两个相邻的元素,将值大的元素交换至右端。
依次比较两个相邻的数,将小数放到前面,大数放到后面
即在第一趟:首先比较第1个数和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此一直继续下去,直到比较最后两个数,将小数放前,大数放后。然后重复第一趟步骤,直到所有排序完成。
第一趟比较完成后,最后一个数一定是数组中最大的一个数,所以第二趟比较的时候最后一个数不参与比较。
第二趟完成后,倒数第二个数也一定是数组中第二大的数,所以第三趟比较的时候最后两个数不参与比较。
依次类推......
输出结果:
冒泡排序的优点: 每进行一趟排序,就会少比较一次,因为每进行一趟排序都会找出一个较大值。如上例:第一趟比较之后,排在最后的一个数一定是最大的一个数,第二趟排序的时候,只需要比较除了最后一个数以外的其他的数,同样也能找出一个最大的数排在参与第二趟比较的数后面,第三趟比较的时候,只需要比较除了最后两个数以外的其他的数,以此类推……也就是说,没进行一趟比较,每一趟少比较一次,一定程度上减少了算法的量。
用时间复杂度来说:
从一个数组中随机选出一个数N,通过一趟排序将数组分割成三个部分,1、小于N的区域 2、等于N的区域 3、大于N的区域,然后再按照此方法对小于区的和大于区分别递归进行,从而达到整个数据变成有序数组。
如下图:
假设最开始的基准数据为数组的第一个元素23,则首先用一个临时变量去存储基准数据,即 tmp=23 ,然后分别从数组的两端扫描数组,设两个指示标志: low 指向起始位置, high 指向末尾。
首先从后半部分开始,如果 扫描到的值大于基准数据 就让 high-1 ,如果发现有元素比该基准数据的值小,比如上面的 18 <= tmp ,就让 high位置的值赋值给low位置 ,结果如下:
然后开始从前往后扫描,如果扫描到的值小于基准数据就让 low+1 ,如果发现有元素大于基准数据的值,比如上图 46 >= tmp ,就再将 low 位置的值赋值给 high 位置的值,指针移动并且数据交换后的结果如下:
然后再开始从前往后遍历,直到 low=high 结束循环,此时low或者high的下标就是 基准数据23在该数组中的正确索引位置 ,如下图所示:
这样一遍遍的走下来,可以很清楚的知道,快排的本质就是把比基准数据小的都放到基准数的左边,比基准数大的数都放到基准数的右边,这样就找到了该数据在数组中的正确位置。
然后采用递归的方式分别对前半部分和后半部分排序,最终结果就是自然有序的了。
输出结果:
最好情况下快排每次能恰好均分序列,那么时间复杂度就是O(nlogn),最坏情况下,快排每次划分都只能将序列分为一个元素和其它元素两部分,这时候的快排退化成冒泡排序,时间复杂度为O(n^2)。
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
将一个数据插入到 已经排好序的有序数据 中
第一趟排序:
用数组的第二个数与第一个数( 看成是已有序的数据 )比较
第二趟排序:
用数组的第三个数与已是有序的数据 {2,3} (刚才在第一趟排的)比较
在第二步中:
...
后面依此类推
输出结果:
选择排序是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
举例:数组 int[] arr={5,2,8,4,9,1}
第一趟排序 : 原始数据: 5 2 8 4 9 1
最小数据1,把1放在首位,也就是1和5互换位置,
排序结果: 1 2 8 4 9 5
第二趟排序 :
第1以外的数据 {2 8 4 9 5} 进行比较,2最小,
排序结果: 1 2 8 4 9 5
第三趟排序 :
除 1、2 以外的数据 {8 4 9 5} 进行比较,4最小,8和4交换
排序结果: 1 2 4 8 9 5
第四趟排序 :
除第 1、2、4 以外的其他数据 {8 9 5} 进行比较,5最小,8和5交换
排序结果: 1 2 4 5 9 8
第五趟排序:
除第 1、2、4、5 以外的其他数据 {9 8} 进行比较,8最小,8和9交换
排序结果: 1 2 4 5 8 9
输出结果:
归并排序(merge sort)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
比如我们对 [8,4,5,7,1,3,6,2] 这个数组进行归并排序,我们首先利用分治思想的“分”将数组拆分。
输出结果: