算法導論的僞代碼使用JS的實現

  • 從今天開始學習算法導論這本書,將自己的學習內容記錄下來。

2.1 插入排序(9頁)

// 下面是僞代碼,參數A爲一個無序的數組,調用INSERTION-SORT方法後,使無序數組A變成有序數組(升序)
INSERTION-SORT(A)
	for j = 2 to A.length
		key = A[j]
		// Insert A[j] into the sorted sequence A[1...j-1].
		i = j-1;
		while i>0 and A[i]>key
			A[i+1] = A[i]
			i = i-1
		A[i+1] = key
// 下面是JS的代碼
function insertion_sort(A) {	// 從數組下標爲1開始,與之它前面的所有下標一一比較
    for (var j = 1; j < A.length; j++) { 	// 因爲僞代碼是從1開始的,而數組是從0開始的,所以這裏的j=1 
        var key = A[j];	// 定義一個臨時變量,存儲當前A[j]的值
        var i = j - 1;	// i = j的前一個數
        while (i >= 0 & A[i] > key) {	// 讓key與A[i]比較,如果A[i]的數大,進入循環,將當前A[i]的值放在下一個下標的位置
            A[i + 1] = A[i];
            i = i - 1;	// 使 i=i-1,直到不滿足條件,跳出循環。
        }
        A[i + 1] = key;	// 循環最後一次的i的位置就是i+1,因爲在循環結束時,i=i-1,所以需要i+1,A[i+1]=key
    }
}
var A = [1,2,3,6,2,4,5,7];
insertion_sort(A);
console.log(A);	// [ 1, 2, 2, 3, 4, 5, 6, 7 ]

2.3 分治法(17頁)

// 僞代碼,參數A是一個數組,參數p是子數組下標第一組有序序列開始的位置,參數q是子數組下標第一組有序序列下標結束的位置,參數r是第二組有序序列下標結束的位置,A的子數組9~16下標包含序列(2,4,5,7,1,2,3,6),調用MERGE(A,9,12,16),結果爲A中的子數組9~16下標是一個有序的序列(1, 2, 2, 3, 4, 5, 6, 7 )
MERGE(A, p, q, r)
	n1 = q - p + 1
	n2 = r - q
	let L[1..n1+1] and R[1..n2+1] be new arrays
	for i = 1 to n1
    	L[i] = A[p+i-1]
	for j = 1 to n2
    	R[j] = A[q+j]
	L[n1+1] =R[n2+1] = ∞
	i = 1
	j = 1
	for k = p to r
    	if L[i] <= R[j]
			A[k] = L[i]
			i = i + 1
		else A[k] = R[j]
			j = j + 1 
// 下面是js的代碼 
function merge(A, p, q, r) {
    n1 = q - p + 1;
    n2 = r - q;
    var L = new Array(n1);
    var R = new Array(n2);
    for (i = 0; i < n1; i++) {
        L[i] = A[p + i];
    }
    for (j = 0; j < n2; j++) {
        R[j] = A[q + j + 1];
    }
    L[n1] = Number.POSITIVE_INFINITY;
    R[n2] = Number.POSITIVE_INFINITY;
    i = 0;
    j = 0;
    for (k = p; k <= r; k++) {
        if (L[i] <= R[j]) {
            A[k] = L[i];
            i = i + 1;
        } else if (A[k] = R[j]) {
            A[k] = R[j];
            j = j + 1;
        }
    }
}
var A = [1,2,3,6,2,4,5,7];
merge(A, 0, 3, 7);
console.log(A);	// [ 1, 2, 2, 3, 4, 5, 6, 7 ]

4.1 最大子數組問題(40頁)

// 僞代碼,返回一個下標數組劃定跨越中點的最大子數組的邊界,並返回最大子數組中值的和。
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
	left-sum = -// 保存目前爲止找到的最大和
	sum = 0		// 保存A[i...mid]中所有值的和
	for i = mid downto low	
    	sum = sum+A[i]
		if sum > left-sum
			left-sum = sum
			max-left = i
	right-sum = -∞	
	sum = 0
	for j = mid + 1 to high
    	sum = sum + A[j]
		if sum > right -sum
			right-sum = sum
			max-right = j
	return (max-left, max-right, left-sum + right-sum)
// 下面是js代碼
function find_max_crossing_subarray(A, low, mid, high) {
    var left_sum = Number.NEGATIVE_INFINITY;
    var sum1 = 0;
    var max_left;
    for (var i = mid; i >= low; i--) {
        sum1 = sum1 + A[i];
        if (sum1 > left_sum) {
            left_sum = sum1;
            max_left = i;
        }
    }
    var right_sum = Number.NEGATIVE_INFINITY;
    var sum2 = 0;
    var max_right;
    for (var j = mid + 1; j <= high; j++) {
        sum2 = sum2 + A[j];
        if (sum2 > right_sum) {
            right_sum = sum2;
            max_right = j
        }
    }
    return [max_left, max_right, left_sum + right_sum]
}
var A = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7];
console.log(find_max_crossing_subarray(A, 0, A.length / 2, A.length - 1));	// [ 7, 10, 43 ]

4.1 最大子數組問題_分治算法(41)

// 僞代碼,在FIND-MAX-CROSSING-SUBARRAY()方法的基礎上實現
FIND-MAXIMUM-SUBARRAY(A, low, high)
	if high == low
		return (low, high, A[low])
	else mid = {(low+high)/2}
    	(left-low, left-high, left-sum) = 
            FIND-MAXIMUM-SUBARRAY(A, low, mid)
		(right-low, right-high, right-sum) = 
            FIND-MAXIMUM-SUBARRAY(A, mid+1, high)
		(cross-low, cross-high, cross-sum) = 
            FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
		if left-sum >= right-sum and left-sum >= cross-sum
			return (left-low, left-high, left-sum)
		elseif rightr-sum >= left-sum and right-sum >= cross-sum
			return (right-low, right-high, right-sum)
		else return (cross-low, cross-high, cross-sum)
// 下面是js代碼
function find_maximum_subarray(A, low, high) {
    // left_set[0]是left-low, left_set[1]是left-high, left_set[2]是left-sum
    // right_set[0]是right-low, right_set[1]是left-high, right_set[2]是right-sum
    // cross_set[0]是cross-low, cross_set[1]是cross-high, cross_set[2]是cross-sum
    var left_set = [];
    var right_set = [];
    var cross_set = [];
    if (high == low) {
        return [low, high, A[low]];
    } else {
        var mid = parseInt((low + high) / 2);
        left_set = find_maximum_subarray(A, low, mid);
        right_set = find_maximum_subarray(A, mid + 1, high);
        cross_set = find_max_crossing_subarray(A, low, mid, high);
        if (left_set[2] >= right_set[2] & left_set[2] >= cross_set[2]) {
            return [left_set[0], left_set[1], left_set[2]];
        } else if (right_set[2] >= left_set[2] & right_set[2] >= cross_set[2]) {
            return [right_set[0], right_set[1], right_set[2]];
        } else {
            return [cross_set[0], cross_set[1], cross_set[2]];
        }
    }
}
console.log(find_maximum_subarray(A, 0, A.length)); // [ 7, 10, 43 ]

未完待更新…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章