1:基本概念
時間複雜度:算法執行所耗費的時間。
這個複雜度直接和樣本的個數有關,複雜度反映了算法的性能,一般來說,複雜度越低,算法所消耗的時間越短。
/* O(N1) */
for (var i = 0; i < data.length; i++) {
...
}
/* O(N2) */
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data.length; j++) {
...
}
}
空間複雜度:運行一個程序所需內存的大小。
空間複雜度和時間複雜度是對立的,比如說,時間複雜度越高,空間複雜度越低;反之則相反。
內排序:所有排序操作都在內存中完成。
2:常用的排序算法
冒泡排序(Bubble Sort)
基本概念:依次比較相鄰的兩個數,將小數放在前面,大數放在後面。
時間複雜度:O(N2)。
實現原理:重複的走訪要排序的數列,一次比較兩個元素,大的元素放後面,如果它們的順序錯誤就把它們交換過來。
代碼實現:有兩層循環嵌套,外循環遍歷數組的每一項,內循環用於兩兩元素的比較,每次內循環減1。
function bubbleSort(arr) {
var length = arr.length;
for (var i = 0; i < length; i++) {
for (var j = 0; j < length - 1 - i; j++) {
if (arr[j] > arr[j+1]) {
[arr[j], arr[j+1]] = [arr[j+1], arr[j]];
}
}
}
return arr;
}
選擇排序(Selection Sort)
時間複雜度:O(N2)。
實現原理:從未排序的序列中找到最小(大)的元素存放到指定的起始位置,再從未排序的序列元素中重複上一步,直至排序完成。
代碼實現:兩層循環嵌套,外循環遍歷數組的每一項,內循環用於找到樣本里面的最小值或者最大值,每次內循環減1。
function selectionSort(arr) {
var length = arr.length;
var minIndex, temp;
for (var i = 0; i < length - 1; i++) {
minIndex = i;
for (var j = i + 1; j < length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
[arr[minIndex], arr[i]] = [arr[i], arr[minIndex]];
}
return arr;
}
快速排序(Quick Sort)
時間複雜度:O(N * log2N)。
實現原理:通過遞歸的方式將數據依次分解爲包含較小元素和較大元素的不同子序列。
代碼實現:找到一個數作爲參考,然後比這個數字大的放在數字左邊,比它小的放在右邊,分別再對左右兩邊的序列做相同的操作。
function partition(arr, low, high) {
let pivot = arr[low];
while (low < high) {
while (low < high && arr[high] > pivot) {
--high;
}
arr[low] = arr[high];
while (low < high && arr[low] <= pivot) {
++low;
}
arr[high] = arr[low];
}
arr[low] = pivot;
return low;
}
function quickSort(arr, low, high) {
if (low < high) {
let pivot = partition(arr, low, high);
quickSort(arr, low, pivot - 1);
quickSort(arr, pivot + 1, high);
}
return arr;
}
插入排序(Insertion Sort)
時間複雜度:O(N2)。
實現原理:構建一個有序序列,未排序數據在已排序序列中從後向前掃描,找到正確位置插入。
代碼實現:兩層循環嵌套,創建已排序數組, 起始包含數組的第一個元素,比這個數字大的放在數字左邊, 比它小的放在右邊。
function insertSort(arr) {
for(let i = 1; i < arr.length; i++) {
for(let j = i; j > 0; j--) {
if(arr[j] < arr[j-1]) {
[arr[j], arr[j-1]] = [arr[j-1], arr[j]];
} else {
break;
}
}
}
return arr;
}