2.1-4 全加器
代码:
Adder(A,B,n)
define C as n+1_bitsarray
Cin = 0 // 进位标志
for i = 1 to n
C[i] = A[i]^B[i]^Cin
Cin = (A[i]&B[i])|(A[i]&Cin)|(B[i]&Cin)
C[n+1] = Cin
return C
2.3-6
二分查找能缩短找到插入位置的时间,但是插入时仍需要移动元素,时间复杂度仍然为 Θ(n2) Θ ( n 2 ) 。采用链表则不能使用二分查找。
2.3-7
伪代码:
Find-two-numbers-sum-to(S,x)
Merge-Sort(S)
for i = 1 to S.length
if Binary-Search(S[i+1...S.length],x-S[i]) == true
return true
return false
2-1 归并-插入排序
a.
每个长度为 k k 的子表对其进行插入排序的最坏时间复杂度为,有 n/k n / k 个子表,总最坏时间复杂度 ank+bn+c a n k + b n + c ,忽略低价与常数项为 Θ(nk) Θ ( n k )
b.
(算法的实现过程是这样的:如果
n≤k
n
≤
k
,则插入排序;否则将表分成两半)
在算法过程中
合并两个长度为
k
k
的子表需要时间,共
n/2k
n
/
2
k
次
合并两个长度为
2k
2
k
的子表需要
a⋅4k+b=4ak+b
a
⋅
4
k
+
b
=
4
a
k
+
b
时间,共
n/4k
n
/
4
k
次
……
合并两个长度为
n/2
n
/
2
的子表需要
a⋅n+b=an+b
a
⋅
n
+
b
=
a
n
+
b
时间,共
1
1
次
总合并时间为
其中 q q 为序列的项数。忽略低阶项和常数项,合并时间为 Θ(nlgnk) Θ ( n lg n k )
c.
k=Θ(lgn) k = Θ ( lg n )
2-2 冒泡排序
a.
还需要证明 A′ A ′ 中的元素都来源于 A A
b.
是
A[j…A.length]
A
[
j
…
A
.
l
e
n
g
t
h
]
中的最小值
证明:
初始化:
j=A.length
j
=
A
.
l
e
n
g
t
h
时明显成立
保持:假设在某次循环前,循环不变式成立。那么在下一次循环之前,如果
A[j]
A
[
j
]
和
A[j−1]
A
[
j
−
1
]
不交换,则有
A[j−1]≤A[j]
A
[
j
−
1
]
≤
A
[
j
]
,如果交换,那么交换之后还是有
A[j−1]≤A[j]
A
[
j
−
1
]
≤
A
[
j
]
。进入下一次循环赋值
j=j−1
j
=
j
−
1
之后,迭代之前,循环不变式仍然成立。
终止:此时
j=i
j
=
i
,有
A[i]
A
[
i
]
是
A[i…A.length]
A
[
i
…
A
.
l
e
n
g
t
h
]
的最小值
c.
循环不等式:
A[1…i−1]
A
[
1
…
i
−
1
]
由
A
A
中第1到第i-1小的数组成,且已经有序。
证明:
初始:第一次迭代之前,
A[1…i−1]为空
A
[
1
…
i
−
1
]
为
空
保持:假设每次迭代之前,循环不等式成立。那么迭代之后,
A[i]
A
[
i
]
是
A[i…A.length]
A
[
i
…
A
.
l
e
n
g
t
h
]
的最小值,意味着
A[i]
A
[
i
]
是
A
A
中第i小的元素(因为第1到第i-1小的数在中)。于是下一次赋值之后(
i=i+1
i
=
i
+
1
)迭代之前,循环不等式仍然成立。
终止:此时
i=A.length+1
i
=
A
.
l
e
n
g
t
h
+
1
,说明
A[1…A.length]
A
[
1
…
A
.
l
e
n
g
t
h
]
由
A
A
中第1到第个组成且已经有序,但“由
A
A
中第1到第个组成”也即原来数组的所有元素。故得证
d.
行 | 每一步时间 | 次数 |
---|---|---|
1 | c1 c 1 | n n |
2 | ∑n−1i=1ti=n+n−1+⋯+2=12(n+2)(n−1) ∑ i = 1 n − 1 t i = n + n − 1 + ⋯ + 2 = 1 2 ( n + 2 ) ( n − 1 ) | |
3 | c3 c 3 | ∑n−1i=1(ti−1)=12n(n−1) ∑ i = 1 n − 1 ( t i − 1 ) = 1 2 n ( n − 1 ) |
4 | c4 c 4 | ∑n−1i=1(ti−1)=12n(n−1) ∑ i = 1 n − 1 ( t i − 1 ) = 1 2 n ( n − 1 ) |
T(n)=c1n+c22(n+2)(n−1)+c3+c42n(n−1)=Θ(n2) T ( n ) = c 1 n + c 2 2 ( n + 2 ) ( n − 1 ) + c 3 + c 4 2 n ( n − 1 ) = Θ ( n 2 )
2-3 Horner规则(秦九韶)
a.
T(n)=c1+c2(n+2)+c3(n+1)=Θ(n) T ( n ) = c 1 + c 2 ( n + 2 ) + c 3 ( n + 1 ) = Θ ( n )
b.
伪代码:
PolySum-Simple(A,x)
y = 0
for i = 0 to n
tmp = 1
for j = 1 to i
tmp *= x
y += A[i]*tmp
return y
最坏时间复杂度 Θ(n2) Θ ( n 2 ) ,比霍纳规则坏
c.
初始化:在第一次迭代前,
i=n,y=0
i
=
n
,
y
=
0
(没有项的和氏为0)
保持:假设在每次迭代前,
y=∑n−(i+1)k=0ak+i+1xk
y
=
∑
k
=
0
n
−
(
i
+
1
)
a
k
+
i
+
1
x
k
成立,也即
y=ai+1+ai+2x+ai+3x2+⋯+anxn−(i+1)
y
=
a
i
+
1
+
a
i
+
2
x
+
a
i
+
3
x
2
+
⋯
+
a
n
x
n
−
(
i
+
1
)
,那么该次迭代后
y=ai+ai+1x+ai+2x2+⋯+anxn−i
y
=
a
i
+
a
i
+
1
x
+
a
i
+
2
x
2
+
⋯
+
a
n
x
n
−
i
,在下次迭代前
i=i−1
i
=
i
−
1
,循环不等式依然成立。
终止:此时
i=−1
i
=
−
1
,有
y=∑nk=0akxk
y
=
∑
k
=
0
n
a
k
x
k
。证毕。
2-4
c.
插入排序中,移动元素的次数等于逆序对的个数,因此运行时间和逆序对的个数的增长量级相同。
d.
Inversion-Number(A,p,q)
if p < q
mid = (p+q)/2