程序员必会十大排序方法
程序员合格必备以及要求必须掌握的
划重点啦~
(一)非比较类排序:
(桶排):-->有桶排序、奇数排序、计数排序
(二)比较类排序:
(交换类) :-->冒泡排序、快速排序
(插入类):-->直接插入排序、希尔排序
(选择类):-->简单选择排序、堆排序
(归并类):-->归并排序
一、冒泡排序
又称起泡排序,基于交换的排序典型,是快排思想的基础,一种稳定排序算法,其时间复杂度为O(n^2)。
基本思想:「循环遍历多次,每次从前往后把大元素往后调,每次确定一个最大(最小)元素,多次后达到排序序列。
冒泡排序:
public class Test {
public static void main(String[] args)
{
// TODO Auto-generated method stub
int [] array= {
-1,2,0,998,101,56,44,88,77};
// 九个数字,正确从小到大排序为:-1,0,2,44,56,77,88,101,998
for(int i=array.length-1;i>=0;i--)
{
for(int j=0;j<i;j++)
{
if(array[j]>array[j+1])
{
int temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
}
for(int i=0;i<array.length;i++)
{
System.out.print(array[i]+" ");
}
}
}
关于冒泡排序还可以看下我以前写过的文字。
二、快速排序
是对冒泡排序的一种改进,采用递归分治的方法,是一种不稳定排序,时间复杂度最坏是O(n^2),平均时间复杂度为O(nlogn),最好情况的时间复杂度为O(nlogn)。
基本思想:
将序列变成两个部分,就是「序列左边全部小于一个数」,「序列右边全部大于一个数」,然后利用递归的思想再将左序列当成一个完整的序列再进行排序,同样把序列的右侧也当成一个完整的序列进行排序。
这个数在这个序列中是可以随机取的,可以取最左边,可以取最右边,当然也可以取随机数。但是「通常」不优化情况下,我们取最左边的那个数。
快速排序:
public void quicksort(int [] a,int left,int right)
{
int low=left;
int high=right;
//下面两句的顺序一定不能混,否则会产生数组越界!!!very important!!!
if(low>high)//作为判断是否截止条件
return;
int k=a[low];//额外空间k,取最左侧的一个作为衡量,最后要求左侧都比它小,右侧都比它大。
while(low<high)//这一轮要求把左侧小于a[low],右侧大于a[low]。
{
while(low<high&&a[high]>=k)//右侧找到第一个小于k的停止
{
high--;
}
//这样就找到第一个比它小的了
a[low]=a[high];//放到low位置
while(low<high&&a[low]<=k)//在low往右找到第一个大于k的,放到右侧a[high]位置
{
low++;
}
a[high]=a[low];
}
a[low]=k;//赋值然后左右递归分治求之
quicksort(a, left, low-1);
quicksort(a, low+1, right);
}
三、直接插入排序:
所有排序算法中的最简单的排序方式之一,一堆高低无序的数据中,从第一个开始,假如前面有比自己高的数据,就直接插入到合适的位置。「一直到队伍的最后一个完成插入」
遍历比较时间复杂度是每次O(n),交换的时间复杂度每次也是O(n),那么n次总共的时间复杂度就是O(n^2)。
二分只能减少查找复杂度每次为O(logn),而插入的时间复杂度每次为O(n)级别,这样总的时间复杂度级别还是O(n^2),而不是O(nlogn)。
插入排序的具体步骤:
---->选取当前位置(当前位置前面已经有序),将当前位置数据插入到前面合适位置。
---->向前枚举或者二分查找,找到要插入的位置
---->移动数组,赋值交换,达到插入效果。
public void insertsort (int a[])
{
int temp=0;
for(int i=1;i<a.length;i++)
{
System.out.println(Arrays.toString(a