1、冒泡排序
冒泡排序的基本思想:遍历整个数组,在遍历中依次对相邻元素进行比较,如果后者的值比前者的大,就交换它们的位置,然后再次遍历数组,重复上述过程直至把所有元素移到合适位置:
动态示意图:
冒泡排序:
/**
* 冒泡排序
* @param array
*/
public static void bubblingSort(int[] array) {
if(array == null || array.length == 0) {
return;
}
int tmp = 0;
boolean a = false;
for(int i = 0;i < array.length-1;i++) {
for(int j = 0;j < array.length-i-1;j++) {
if(array[j] > array[j+1]) {
a = true;
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
if(a == false) {
break;
}
}
}
2、直接插入排序
直接插入排序的基本思想:将要排序的数组分为有序部分和无序部分,每次从无序部分拿一个元素插入到有序部分的合适位置。通常在排序前,有序部分为数组的第一个元素。
越有序越快!!
动态示意图:
直接插入排序:
/**
* 直接插入排序
* @param array
*/
public static void insertSort(int[] array) {
if(array == null || array.length == 0) {
return;
}
int tmp = 0,j;
for(int i = 1;i < array.length;i++) {
tmp = array[i];
for(j = i-1;j >= 0;j--) {
if(array[j] > tmp) {
array[j+1] = array[j]; //比tmp大的向后移
}else {
//直到找到比tmp小的停止比较,因为每次比较前面的已经有序,只是在找tmp应该插入的位置
break;
}
}
array[j+1] = tmp; //把tmp放到当前已排序的数据中应该放入的位置
}
}
3、选择排序
选择排序的基本思想:每一趟都从待排序的数组元素中选择最大的(或者最小的)一个元素,并放在已排好序的数列后面,一直重复上述动作,直至把待排序的数组元素排完。
可以这么理解,冒泡排序就是把大的数据往后放,而选择排序是把小的数据往前放;
动态示意图:
选择排序:
/**
* 选择排序
* @param array
*/
public static void selectSort(int[] array) {
if(array == null || array.length == 0) {
return;
}
int tmp = 0;
for(int i = 0;i < array.length;i++) {
for(int j = i+1;j < array.length;j++) {
if(array[i] > array[j]) {
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
}
}
4、希尔排序
又叫sell排序,希尔排序思想:原理有点像直接插入法,但它可以减少数据搬移次数,排序的原则是将数据分成特定间隔的小组,以直接插入法排完小组内的数据后再减少间隔的距离重新分组,再排序,再分再排,最后以所有数据为一个大组,再用直接插入法比较,因为直接插入法就是越有序越快,所以分组每组排序后就让每组数据变得有序,提高了算法的效率,所以sell排序也叫直接插入法的优化。
分治法!
动态示意图:
/**
* sell排序
* @param array
* @param gap
*/
public static void sell(int[] array,int gap) {//gap分组
if(array == null || array.length == 0) {
return;
}
int tmp = 0;
int j = 0;
for(int i = gap;i < array.length;i++) {
tmp = array[i];
for(j = i-gap;j >= 0;j -= gap) {
if(array[j] > tmp) {
array[j+gap] = array[j];
}else {
break;
}
}
array[j+gap] = tmp;
}
}
/**
* sell排序分组
* @param array
*/
public static void sellSort(int[] array){
int[] d = {3,1};//分组
for(int i=0;i<d.length;i++){
sell(array,d[i]);//调用比较方法,也就是变态了的直接插入排序法
}
}
5、四种排序总结:
排序名称 | 最好情况下的复杂度(数据本身有序) | 最坏情况下的复杂度 | 稳定性 | 备注 |
---|---|---|---|---|
冒泡排序 | O(n) | O(n^2) | 稳定 | 把大的放后面 |
直接插入排序 | O(n) | O(n^2) | 稳定 | 把从无序部分拿到的数据放到有序部分它该放的位置 |
选择排序 | O(n^2) | O(n^2) | 不稳定 | 把小的放前面 |
sell排序 | O(n) | O(n^2) | 不稳定 | 分组用直接插入排序 |