1、冒泡排序:
(1)平均時間複雜度:O(n2)
(2)最好時間複雜度:O(n)
(3)最壞時間複雜度:O(n2)
(5)空間複雜度:O(1)
(5)穩定性:穩定
(6)JavaScript實現:
function bubble ( arr ) {
var len = arr.length;
var tmp;
// 外層循環負責控制排序的趟數
for(var i = 0; i < len - 1; i++){
// 內層循環負責進行一趟排序
for(var j = 0; j < len - 1 - i; j++){
if(arr[j + 1] < arr[j]){
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
};
};
};
return arr;
};
2、選擇排序:
(1)平均時間複雜度:O(n2)
(2)最好時間複雜度:O(n2)
(3)最壞時間複雜度:O(n2)
(4)空間複雜度:O(1)
(5)穩定性:不穩定
(6)JavaScript實現:
function select( arr ) {
var len = arr.length;
// 外層循環需要進行len - 1趟排序
for(var i = 0; i < len - 1; i++){
var index = i;
var min = arr[i];
var tmp;
// 內層循環從未排序的數組元素中比較出最小的一個
for(var j = i + 1; j < len; j++){
if(min > arr[j]){
index = j;
min = arr[j];
};
};
// 將其放在排序後的數組元素的最後
tmp = arr[i];
arr[i] = min;
arr[index] = tmp;
};
};
3、插入排序:
(1)平均時間複雜度:O(n2)
(2)最好時間複雜度:O(n)
(3)平均時間複雜度:O(n2)
(4)空間複雜度:O(1)
(5)穩定性:穩定
(6)JavaScript實現:
遍歷數組,遍歷到i時,a0,a1...ai-1是已經排好序的,取出ai,從ai-1開始向前和每個比較大小,如果小於,則將此位置元素向後移動,繼續先前比較,如果不小於,則放到正在比較的元素之後。可見相等元素比較是,原來靠後的還是拍在後邊,所以插入排序是穩定的。
當待排序的數據基本有序時,插入排序的效率比較高,只需要進行很少的數據移動。
function insert ( arr ) {
var len = arr.length;
var tmp;
for(var i = 1; i < len; i++){
// 取出當前的數組元素
tmp = arr[i];
for(var j = i - 1; j >= 0; j--){
if (arr[j] > tmp) {
arr[j+1] = arr[j];
} else {
break;
};
};
// 插入取出的數組元素
arr[j+1] = tmp;
};
return arr;
}
4、希爾排序:
(1)平均時間複雜度:O(nlogn) ~ O(n2)
(2)最好時間複雜度:O(n1.3)
(3)最壞時間複雜度:O(n2)
(4)空間複雜度:O(1)
(5)穩定性:不穩定
(6)JavaScript實現:
// 插入排序
function sort( arr, di ){
for(var i = di; i < arr.length; i++){
var guard = arr[i];
for(var j =i -di; j >= 0 && guard < arr[j]; j -= di){
arr[j+di] = arr[j];
};
arr[j+di] = guard;
};
return arr;
}
// 希爾排序,本質上是以不同的步長多次進行插入排序
// 步長的選擇對希爾排序的效率有顯著影響
function shell ( arr ) {
var di = parseInt( arr.length / 2 );
while ( di >= 1) {
arr = sort( arr, di);
di = parseInt( di / 2 );
};
return arr;
};
5、歸併排序:
(1)平均時間複雜度:O(nlogn)
(2)最好時間複雜度:O(nlogn)
(3)最壞時間複雜度:O(nlogn)
(4)空間複雜度:O(n)
(5)穩定性:穩定
(6)JavaScript實現:
// 對被歸併的左右兩個數組進行歸併排序
// 被輸入的左右兩個數組,都是有序的。
function merge (left, right){
var l = 0,
r = 0;
var result = [];
// 對左右兩個數組的首項,進行比較,較小的推入棧中。
while(l < left.length && r < right.length){
if(left[l] < right[r]){
result.push( left[l] );
l += 1;
} else {
result.push( right[r] );
r += 1;
};
};
// 經過上面的比較,左右兩個數組,必定有一個數組比較完畢,一個沒有比較完畢。
// 但是,在不同情況的遞歸層,有不同的表現,故而將二者未比較的元素都連接到result中。
// 由於,左右兩個數組在輸入前就是有序的,剩餘未經比較的數組元素也是有序的,且都大於之前經過比較的數組元素,故而可以將其連接到result。
// 下方的代碼,實質上是將左右數組中,未經比較的數組元素連接到result。
result = result.concat( left.slice(l) );
result = result.concat( right.slice(r) );
return result;
};
function mergeSort ( arr ){
var len = arr.length;
// 結束遞歸
if(len <= 1){
return arr;
};
// 切割數組,並對切割後的數組進行遞歸操作
var middle = Math.floor( len/2 );
var left = mergeSort( arr.slice(0, middle) );
var right = mergeSort( arr.slice(middle) );
// 完成遞歸後,進行歸併
return merge(left, right);
}
6、快速排序:
(1)平均時間複雜度:O(nlogn)
(2)最好時間複雜度:O(nlogn)
(3)最壞時間複雜度:O(n2)
(4)空間複雜度:O(logn) ~ O(n)
(5)穩定性:不穩定
(6)JavaScript實現:
function quick ( arr ) {
var less = [],
pivotList = [],
more = [],
result = [],
len = arr.length;
// 結束遞歸
if(len <= 1){
return arr;
};
// 與基準對比,將數組劃分爲小,中,大三組
var pivot = arr[0];
for(var i = 0; i <len; i++){
if(arr[i] < pivot){
less.push(arr[i]);
} else if(arr[i] > pivot){
more.push(arr[i]);
} else {
pivotList.push(arr[i]);
};
};
// 遞歸地對劃分出的小、大兩個組進行快速排序
less = quick(less);
more = quick(more);
// 將排序好的小,中,大三組連接起來
result = result.concat(less, pivotList, more);
return result;
}