本专栏首先介绍十大经典排序算法。
参考的文章有:
(1)这或许是东半球讲十大排序算法最好的一篇文章
(2)排序算法 - 面试中的排序算法总结
(3)必学十大经典排序算法,看这篇就够了
普通
(1)两重循环,两两依次比较,按照谁大(小)谁向后移动,第一次内层循环结束后,就会将最大(小)的元素置于最后一个位置;
(2)第二次循环只需要比较前n-1个元素的大小了,因此j < len - i - 1
;
(3)重复以上过程直到结束。
/**
* 升序
* @param arr
* @return
*/
public int[] bubbleSortInc(int[] arr){
int len = arr.length;
for(int i = 0; i < len; i++){
for(int j = 0; j < len - i - 1; j++){
if(arr[j] > arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
return arr;
}
/**
* 降序
* @param arr
* @return
*/
public int[] bubbleSortDec(int[] arr){
int len = arr.length;
for(int i = 0; i < len; i++){
for(int j = 0; j < len - i - 1; j++){
if(arr[j] < arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
return arr;
}
优化1
(1)考虑一种特殊情况:给定数组是排好序的,而本算法并不会判断并提前结束,而是仍旧固执的执行完两重循环,因此我们增加一个判断变量,来提前结束。
(2)boolean isSort = true;
假设一开始每一次的内存循环都为排好序的状态,如果没排好,则会进入if条件语句isSort = false;
;反之则直接break,结束外层for循环。
/**
* 冒泡升序-优化1
* @param arr
* @return
*/
public int[] bubbleSortInc2(int[] arr){
int len = arr.length;
for(int i = 0; i < len; i++){
// 默认已经排好序了
boolean isSort = true;
for(int j = 0; j < len - i - 1; j++){
if(arr[j] > arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
isSort = false;
}
}
if(isSort){
break;
}
}
return arr;
}
优化2
(1)在优化1的基础上再考虑一种特殊情况,局部是排好序的,所以仍旧是固执的执行完两重循环,所以我们增加一个变量记录最后一次修改的位置 。
(2)int index = 0; index = j;
用来记录最后一次进入if条件中进行判断的位置。
(3)当前一次循环结束后,就将j
的终止位置设置为end = index;
(4)需要注意的是int end = len -1;
,后面直接复制为index即可
/**
* 冒泡升序-优化2
* @param arr
* @return
*/
public int[] bubbleSortInc3(int[] arr){
int len = arr.length;
int index = 0;
int end = len -1;
for(int i = 0; i < len; i++){
// 默认是已经排好序了
boolean isSort = true;
for(int j = 0; j < end; j++){
if(arr[j] > arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
index = j;
isSort = false;
}
}
end = index;
if(isSort){
break;
}
}
return arr;
}