本文仅自己学习排序算法之后的总结,若有错误,请大家指正!!
排序算法主要分为三个梯队:
冒泡排序;选择排序;插入排序
它们的共同点是:平均时间复杂度都是O(N^2)。
它们之间有什么样的差别呢?
首先,从性能来分析,冒泡排序和插入排序的元素比较交换次数取决于原始数组的有序程度。
如果原始数组本来已经接近有序,只需要较少的比较交换次数即可完成排序。比如下面这个数组,只有7和8是逆序的:
如果原始数组大部分元素无序,则需要较多的比较交换次数。
在此基础上,插入排序的性能略高于冒泡排序。为什么这么说呢?因为冒泡排序每两个元素之间的交换是彼此独立的,比如A和B交换,B和C交换,C和D交换:
而插入排序的元素交换是连续的,比如把B赋值给A,把C赋值给B,把D赋值给C,最后把A赋值给D:
再来说说选择排序,选择排序和前面两者不太一样,它的元素比较交换次数是固定的,和原始数组的有序程度无关。
因此,当原始数组接近有序时,插入排序性能最优;当原始数组大部分元素无序时,选择排序性能最优。
从稳定性上分析:
冒泡排序和插入排序是稳定排序,值相同的元素在排序后仍然保持原本的先后顺序。
选择排序是不稳定排序,值相同的元素在排序后不一定保持原本的先后顺序。
原始的冒泡排序是稳定排序,该算法每一轮要遍历所有的元素,轮转次数和元素数量相当,所以时间复杂度为O(N^2),原始代码如下:
private static void sort(int array[])
{
int tmp = 0;
for(int i = 0; i < array.length; i++){
for(int j = 0; j < array.length - i - 1; j++)
{
if(array[j] > array[j+1])
{
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
}
public static void main(String[] args){
int[] array = new int[]{
5,8,6,3,9,2,1,7};
sort(array);
System.out.println(Arrays.toString(array));
}
选择排序与冒泡排序类似,就不一一编写代码了。
插入排序的代码如下:
public static void sort(int[] array){
for(int i=1