排序演算法集合

鬧鬧不愛鬧發表於2019-03-16

一. 氣泡排序

// 思路:比較相鄰的元素,每次比較都會生成最大或者最小值放在最後,所以每輪比較次數會遞減
function sort(arr) {
    for (let i = 0; i < arr.length - 1; i += 1) { // 一共比較length - 1輪
        for (let j =0; j < arr.length - 1 - i; j += 1) { // 每輪比較的次數(遞減)
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
            }
        }
    }
}複製程式碼

二. 快排

// 思路:雙指標 + 遞迴分治。每次比較都能找到基值的位置,然後遞迴比較基值左右的部分
function sort(arr, start, end) {
    if (start >= end) return;
    let left = start, right = end;
    const basic = arr[start]; // 基值
    while(left < right) {
        while(left < right && arr[right] >= basic ) right--; // 右指標比較直到找到比基值小的值則暫停
        while(left < right && arr[left] <= basic) left++; // 左指標比較直到找到比基值大的值則暫停
        [arr[left], arr[right]] = [arr[right], arr[left]] // 交換左右指標所指的值
    }
    [arr[start], arr[left]] = [arr[left], arr[start]];
    // 左右分治
    sort(arr, start, left - 1);
    sort(arr, left + 1, end);
}

複製程式碼

三. 選擇排序

// 思路:和冒泡有點相似,每輪比較得出該輪的最小值,然後把最小值放在最前面;然後比較剩下的值,得出次小值。
function sort(arr) {
    var l = arr.length;
    for (let i = 0; i < l; i += 1) {
        var c = arr.slice(i, l); // 每次擷取剩下的元素進行比較
	var min = Math.min(...c); // 獲取到當前被比較的元素的最小值
	var index = arr.indexOf(min); // 獲取到最小值所在的索引位置
	arr.splice(index, 1); // 將最小值從當前元素集中剔除
	arr.splice(i, 0, min) // 將最小值移動到前面位置
    }
	return arr;
}複製程式碼

四. 插入排序

// 思路: 從陣列的第二項開始,將元素和該元素之前的元素級比較,如果比前面的元素小,則繼續往前比較,直至
        比較到第一個位置或者出現該元素大於前面的元素為止。將該元素插到這個位置。
function sort(arr) {
    for (let i = 1; i < arr.length; i += 1) {
        let j = i; // 記錄當前元素前面有幾個元素
        const temp = arr[i]
        while(j > 0 && temp < arr[j - 1]) { // 將該元素和之前的元素比較,直到找到大於前面元素的位置
            j--;
        }
        if (j != i) {
           arr.splice(i, 1);
           arr.splice(j, 0, temp); // 將temp移動到j的位置
        }
    }
    return arr;
}複製程式碼

五. 希爾排序

思路: 。。。。。。
function sort(arr) {
	for (let z = Math.floor(arr.length / 2); z >= 1; z = Math.floor(z / 2)) {
		for (let i = 0; i < arr.length && arr[i + z]; i += 1) {
			if (arr[i] > arr[i + z]) {
				[arr[i], arr[i + z]] = [arr[i + z], arr[i]];
			}
		}
	}
	return arr;
}複製程式碼

六. 計數排序

思路: 建立另一個陣列來對映來源陣列,對映規則為陣列的索引對應來源陣列的值,陣列索引對應的值對映來源陣列值出現的次數。
       舉個例子:
const originArr = [4,3,2,1,3,2]; => const mapArr = [0, 1, 2, 2, 1]; 
實現:
function sort(arr) {
	const max = Math.max(...arr); // 建立一個長度為源陣列最大值的陣列
	const arr2 = new Array(max + 1);
	arr2.fill(0, 0); // 為對映陣列初始化值
	for (let i = 0; i < arr.length; i += 1) {
		const v = arr[i];
		arr2[v]++;
	}
	const results = [];
	let index = 0;
	for (let j = 0; j < arr2.length; j += 1) {
		while(arr2[j]) {
			results[index++] = j;
			arr2[j]--;
		}
	}
	return results;
}複製程式碼


相關文章