1. O(n^2)的排序算法
1.1 冒泡排序(Bubble Sort)
假如我们要排序这个数组:【8,6,2,3,1】
第一次(0-4):【6,8,2,3,1】-->【6,2,8,3,1】--> 【6,2,3,8,1】-->【6,2,3,1,8】
第二次(0-3):【2,6,3,1,8】-->【2,3,6,1,8】-->【2,3,1,6,8】
第三次(0-2):【2,3,1,6,8】-->【2,1,3,6,8】
第四次(0-1):【1,2,3,6,8】
public class _01_BubbleSort {
// 我们的算法类不允许产生任何实例
private _01_BubbleSort(){}
public static void sort(Comparable[] arr){
for(int i=0 ; i<arr.length ; i++){
for(int j=0 ; j<arr.length-i-1; j++){
if(arr[j].compareTo(arr[j+1])>0){
swap(arr,j,j+1);
}
}
}
}
}
1.2 选择排序(Selection Sort)
假如我们要排序这个数组:【8,6,2,3,1,5,7,4】
我们首先找到序号(0-7)中最小值1,让1与序号为0的值交换:【1,6,2,3,8,5,7,4】
我们再找到序号(1-7)中最小值2,让2与序号为1的值交换:【1,2,6,3,8,5,7,4】
我们再找到序号(2-7)中最小值3,让3与序号为2的值交换:【1,2,3,6,8,5,7,4】
继续。。。。。。。
我们来看下代码
//选择排序
public class _02_SelectionSort {
// 我们的算法类不允许产生任何实例
private _02_SelectionSort(){}
public static void sort(Comparable[] arr){
int n = arr.length;
for( int i = 0 ; i < n ; i ++ ){
int minIndex = i; // 寻找[i, n)区间里的最小值的索引
for( int j = i + 1 ; j < n ; j ++ )
if( arr[j].compareTo( arr[minIndex] ) < 0 ) // 使用compareTo方法比较两个Comparable对象的大小
minIndex = j;
swap( arr , i , minIndex);
}
}
}
1.3 插入排序(Insertion Sort)
假如我们要排序这个数组:【8,6,2,3,1,5,7,4】
首先我们考虑序号为0的元素,因为序号0是第一个元素 ,所以不用动:【8,6,2,3,1,5,7,4】
我们考虑序号为1的元素,我们把元素6放在序号(0-1)中合适的位置:【6,8,2,3,1,5,7,4】
我们考虑序号为2的元素,我们把元素2放在序号(0-2)中合适的位置:【2,6,8,3,1,5,7,4】
我们考虑序号为3的元素,我们把元素3放在序号(0-3)中合适的位置:【2,3,6,8,1,5,7,4】
继续。。。。。。
//使用优化的BubbleSort
public class _01_BubbleSort {
// 我们的算法类不允许产生任何实例
private _01_BubbleSort(){}
public static void sort(Comparable[] arr){
for(int i=0 ; i<arr.length ; i++){
for(int j=0 ; j<arr.length-i-1; j++){
if(arr[j].compareTo(arr[j+1])>0){
swap(arr,j,j+1);
}
}
}
}
}
相比选择排序,插入排序的一个优点是提前终止,不用遍历整个数组,因此,插入排序应该要比选择排序的效率更加高效,但是如果测试你会发现,选择排序会快些,为什么呢,因为插入排序每交换个位置,就要赋值三次,在这里浪费了大量时间,所以当我们用上面代码方法3就能避免这个问题,时间就比选择排序快了