- 從今天開始學習算法導論這本書,將自己的學習內容記錄下來。
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 ]
未完待更新…