1)分类: java
1)插入排序(直接插入排序、希尔排序) 算法
2)交换排序(冒泡排序、快速排序) 数组
3)选择排序(直接选择排序、堆排序) ui
4)归并排序 spa
5)分配排序(箱排序、基数排序) code
所需辅助空间最多:归并排序 排序
所需辅助空间最少:堆排序 递归
平均速度最快:快速排序 it
不稳定:快速排序,希尔排序,堆排序。 io
1)选择排序算法的时候
1.数据的规模 ; 2.数据的类型 ; 3.数据已有的顺序
通常来讲,当数据规模较小时,应选择直接插入排序或冒泡排序。任何排序算法在数据量小时基本体现不出来差距。考虑数据的类型,好比若是所有是正整数,那么考虑使用桶排序为最优。 考虑数据已有顺序,快排是一种不稳定的排序(固然能够改进),对于大部分排好的数据,快排会浪费大量没必要要的步骤。数据量极小,而起已经基本排好序,冒泡是最佳选择。咱们说快排好,是指大量随机数据下,快排效果最理想。而不是全部状况。
快速排序:
快 速排序是对冒泡排序的一种改进。它的基本思想是:经过一躺排序将要排序的数据分割成独立的两部分,其中一部分的全部数据都比另一不部分的全部数据都要 小,而后再按次方法对这两部分数据分别进行快速排序,整个排序过程能够递归进行,以此达到整个数据变成有序序列。最坏状况的时间复杂度为O(n2),最好 状况时间复杂度为O(nlog2n)。
假设要排序的数组是A[1]……A[N],首先任意选取一个数据(一般选用第一个数据)做为关键数据,而后将全部比它的数都放到它前面,全部比它大的数都放到它后面,这个过程称为一躺快速排序。一趟快速排序的算法是:
1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;
2)以第一个数组元素做为关键数据,赋值给X,即X:=A[1];
3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,二者交换;
4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,二者交换;
5)、重复第三、4步,直到I=J;
例如:待排序的数组A的值分别是:(初始关键数据X:=49)
A[1] A[2] A[3] A[4] A[5] A[6] A[7]:
49 38 65 97 76 13 27
进行第一次交换后: 27 38 65 97 76 13 49
( 按照算法的第三步从后面开始找)
进行第二次交换后: 27 38 49 97 76 13 65
( 按照算法的第四步从前面开始找>X的值,65>49,二者交换,此时I:=3 )
进行第三次交换后: 27 38 13 97 76 49 65
( 按照算法的第五步将又一次执行算法的第三步从后开始找)
进行第四次交换后: 27 38 13 49 76 97 65
( 按照算法的第四步从前面开始找大于X的值,97>49,二者交换,此时J:=4 )
此时再执行第三步的时候就发现I=J,从而结束一躺快速排序,那么通过一躺快速排序以后的结果是:27 38 13 49 76 97 65,即因此大于49的数所有在49的后面,因此小于49的数所有在49的前面。
快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行相似的快速排序,从而完成所有数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:
初始状态 {49 38 65 97 76 13 27}
进行一次快速排序以后划分为 {27 38 13} 49 {76 97 65}
分别对先后两部分进行快速排序 {13} 27 {38}
结束 结束 {49 65} 76 {97}
49 {65} 结束
结束
图6 快速排序全过程
/** * 快速排序实现算法 * @author Administrator */ public class SortTest { /** * @param args */ public static void main(String[] args) { // TODO 自动生成方法存根 quicksort qs = new quicksort(); int data[] = {44,22,2,32,54,22,88,77,99,11}; qs.data = data; qs.sort(0, qs.data.length-1); qs.display(); } } class quicksort { public int data[]; /*分割、分开*/ private int partition(int sortArray[],int low,int hight) { int key = sortArray[low]; while(low<hight) { while(low<hight && sortArray[hight]>=key) hight--; sortArray[low] = sortArray[hight]; while(low<hight && sortArray[low]<=key) low++; sortArray[hight] = sortArray[low]; } sortArray[low] = key; return low; } public void sort(int low,int hight) { if(low<hight) { int result = partition(data,low,hight); sort(low,result-1); sort(result+1,hight); } } public void display() { for(int i=0;i<data.length;i++) { System.out.print(data[i]); System.out.print(" "); } } }
堆排序:首先,数组里面用层次遍历的顺序放一棵彻底二叉树。从最后一个非终端结点往前面调整,直到到达根结点,这个时候除根节点之外的全部非终端节点都已经知足堆得条件了,因而须要调整根节点使得整个树知足堆得条件,因而从根节点开始,沿着它的儿子们往下面走(最大堆沿着最大的儿子走,最小堆沿着最小的儿子走)。主程序里面,首先从最后一个非终端节点开始调整到根也调整完,造成一个heap, 而后将heap的根放到后面去(即:每次的树大小会变化,可是 root都是在1的位置,以方便计算儿子们的index,因此若是须要升序排列,则要逐步大顶堆。由于根节点被一个个放在后面去了。降序排列则要创建小顶堆)