2.1-1
初始 31 41 59 26 41 58
第一遍 31 41 59 26 41 58
第二遍 31 41 59 26 41 58
第三遍 26 31 41 59 41 58
第四遍 26 31 41 41 59 58
第五遍 26 31 41 41 58 59
2.1-2
把顺序改成非递增只要把判断大小时的条件改成小于即可
1
2
3
4
5
6
7
8
|
Insertion-Sort(A)
for
j = 2 to A.length
key = A[j]
i = j - 1
while
i > 0 and A[i] < key
A[i + 1] = A[i]
i = i - 1
A[i + 1] = key
|
2.1-3
1
2
3
4
5
|
Linear-Search(A, v)
for
i = 1 to A.length
if
A[i] == v
return
i
return
NIL
|
2.1-4
Input: 两个n比特序列 A={a1,a2,…,an} A={a1,a2,…,an} B={b1,b2,…,bn} B={b1,b2,…,bn}
Output: 一个n+1比特序列 C={c1,c2,…,cn+1} C={c1,c2,…,cn+1} 使得等式 (cn+1cn…c2c1)2=(anan−1…a2a1)2+(bnbn−1…b2b1)2 (cn+1cn…c2c1)2=(anan−1…a2a1)2+(bnbn−1…b2b1)2 成立
利用全加器的逻辑位运算可以简单得到每一位的结果和进位。
1
2
3
4
5
6
7
8
9
10
11
|
Binary-Addition(A, B)
inc = 0
i = 1
while
i <= A.length
k = A[i] xor B[i]
g = A[i] and B[i]
C[i] = k xor inc
inc = inc and k or g
i = i + 1
C[i] = inc
return
C
|
2.2-1
Θ(n3) Θ(n3)
2.2-2
1
2
3
4
5
6
7
8
9
|
Selection-Sort(A)
for
i = 1 to A.length - 1
min = i
for
j = i + 1 to A.length
if
A[j] < A[min]
min = j
tmp = A[min]
A[min] = A[i]
A[i] = tmp
|
2.2-3
第i个元素为所找元素需要的比较次数为i
如果每个元素被找的几率相同且必定查找成功的时候,平均比较次数 c=(1+2+...+n)/n=(n+1)/2 c=(1+2+...+n)/n=(n+1)/2
当元素不存在或者是最后一个元素的时候需要比较的次数最多,为n次。
平均和最坏时间复杂度都是 Θ(n) Θ(n)
2.2-4
当输入有可能就是结果(比如排序)或者能够直接算出的情况(比如全零矩阵相乘),直接输出结果。
2.3-1
[3 9 26 38 41 49 52 57] [3 26 41 52] [9 38 49 57] [3 41] [26 52] [38 57] [9 49] [3] [41] [52] [26] [38] [57] [9] [49]
2.3-2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
Merge(A, p, q, r)
n1 = q - p + 1
n2 = r - q
let L[1..n1] and R[1..n2] be
new
arrays
for
i = 1 to n1
L[i] = A[p + i - 1]
for
j = 1 to n2
R[i] = A[q + j]
i = 1, j = 1, k = p
while
i <= n1 and j <= n2
if
L[i] <= R[j]
A[k] = L[i]
i = i + 1
else
A[k] = R[j]
j = j + 1
k = k + 1
while
i <= n1
A[k] = L[i]
i = i + 1
k = k + 1
while
j <= n2
A[k] = R[j]
j = j + 1
k = k + 1
|
2.3-3
当n=2时, T(n)=2∗lg2=2 T(n)=2∗lg2=2 满足;
假设当n=k时有 T(k)=k∗lgk T(k)=k∗lgk ,
那么当n=2k时有
T(2k)=2T(k)+2k=2klgk+2k=2klgk+2klg2=2klg2k T(2k)=2T(k)+2k=2klgk+2k=2klgk+2klg2=2klg2k
得证。
2.3-4
1
2
3
4
5
6
7
8
9
|
Insertion-Sort(A, n)
if
n > 1
Insertion-Sort(A, n - 1)
i = n - 1
key = A[n]
while
i > 0 and A[i] > key
A[i + 1] = A[i]
i = i - 1
A[i + 1] = key
|
2.3-5
1
2
3
4
5
6
7
8
9
10
11
|
Binary-Search(A, v)
low = 1, high = A.length
while
low <= high
mid = (low + high) / 2
if
A[mid] == v
return
mid
else
if
A[mid] < v
low = mid + 1
else
high = mid - 1
return
NIL
|
2.3-6
不可以,因为虽然每次查找的时间复杂度为 Θ(lgn) Θ(lgn) 但是把元素放到正确的位置仍然需要移动同样多的元素,所以复杂度没有变化,在n比较大的时候系数可能会变小一点。
2.3-7
1
2
3
4
5
6
7
8
9
10
11
12
|
Sum-Exist(A, x)
Merge-Sort(A)
low = 1, high = A.length
while
low < high
sum = A[low] + A[high]
if
sum == x
return
true
else
if
sum > x
high = high - 1
else
low = low + 1
return
false
|
2-1
a. 每个子序列的元素数量为k,最差的情况下需要进行 k(k−1)/2 k(k−1)/2次基础操作,一共有 n/k n/k个子序列,所以总的基础操作次数为
2-2
a. 需要证明最终的序列是非递减的,还需要证明最终序列是原序列的一种排列。
b.
2-3
a. 循环中的运算可以在常量时间内完成,所以复杂度是 Θ(1) Θ(1),循环次数为n,所以总的时间复杂度为 Θ(n) Θ(n)。
b.
1
2
3
4
5
6
7
8
|
Evaluate-Polynomial(A, x, n)
y = 0
for
k = 0 to n
t = 1
for
i = 1 to k
t = t * x;
y = y + A[k] * t
return
y
|
2-4
a. (8, 6) (2, 1) (3, 1) (8, 1) (6, 1)
b. 拥有逆序数最多的是 {n,n−1,⋯,3,2,1} {n,n−1,⋯,3,2,1},其中任意两个数之间都是逆序的,所以总计 n(n−1)/2 n(n−1)/2个。
c. 逆序数应该与元素移动的数量相同。插入排序每次移动元素都将一个较大的数移到较小的数后面,使得总逆序数减少1,而排序完成后逆序数是0,所以开始的逆序数和元素移动的次数相同。
d.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
Merge-Inversion(A, p, q, r)
n1 = q - p + 1
n2 = r - q
let L[1..n1] and R[1..n2] be
new
arrays
for
i = 1 to n1
L[i] = A[p + i - 1]
for
j = 1 to n2
R[i] = A[q + j]
i = 1, j = 1, k = p, inv = 0
while
i <= n1 and j <= n2
if
L[i] <= R[j]
A[k] = L[i]
i = i + 1
else
inv = inv + n1 - i + 1
A[k] = R[j]
j = j + 1
k = k + 1
while
i v= n1
A[k] = L[i]
i = i + 1
k = k + 1
while
j <= n2
A[k] = R[j]
j = j + 1
k = k + 1
return
inv
Calculate-Inversion(A, p, r)
inv = 0
if
p < r
q = (p + r) / 2
inv = inv + Calculate-Inversion(A, p, q)
inv = inv + Calculate-Inversion(A, q, r)
inv = Merge-Inversion(A, p, q, r)
return
inv
|