算法导论第三版2.1答案
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
大于号改成小于号就可以。
void i_sort(int a[], int n)
{
for(int i = 2; i <= n; ++i)
{
int v = a[i], j = i - 1;
for(; j && a[j] < v; --j) a[j + 1] = a[j];
a[j + 1] = v;
}
}
2.1-3
线性查找算法,循环不变式为:
在每次循环迭代开始前,
a
[
1
:
i
−
1
]
a[1:i - 1]
a[1:i−1]中没有值为v的元素。
证明:
初始化:在循环第一次迭代前,
a
[
1
:
i
−
1
]
为空,成立。
保持:每次迭代时,都有
a
[
1
:
i
−
1
]
未出现过
v
,且若
a
[
i
]
=
v
,
程序返回
i
,符合要求;若
a
[
i
]
≠
v
,
则继续下一次迭代,并且保证
a
[
1
:
i
]
中没有出现过
v
。
终止
:
由保持的分析可知,
a
[
1
:
n
]
中出现过
v
,一定能返回其出现的位置
i
,且此时
a
[
1
:
i
−
1
]
没有过
v
。当
a
[
1
:
n
]
中都没有出现过
v
,也就是最后一次迭代都结束后,此时
i
=
n
+
1
,
a
[
1
:
n
]
中都没有出现过
v
,程序会返回
N
I
L
,符合要求。
初始化: 在循环第一次迭代前,a[1:i - 1]为空,成立。\\ 保持: 每次迭代时,都有a[1:i-1]未出现过v,且若a[i]=v, 程序返回i,符合要求;若a[i] \neq v,则继续下一次迭代,并且保证a[1:i]中没有出现过v。\\ 终止: 由保持的分析可知,a[1:n]中出现过v,一定能返回其出现的位置i,且此时a[1:i-1]没有过v。当a[1:n]中都没有出现过v,也就是最后一次迭代都结束后,此时i = n+1, a[1:n]中都没有出现过v,程序会返回NIL,符合要求。
初始化:在循环第一次迭代前,a[1:i−1]为空,成立。保持:每次迭代时,都有a[1:i−1]未出现过v,且若a[i]=v,程序返回i,符合要求;若a[i]=v,则继续下一次迭代,并且保证a[1:i]中没有出现过v。终止:由保持的分析可知,a[1:n]中出现过v,一定能返回其出现的位置i,且此时a[1:i−1]没有过v。当a[1:n]中都没有出现过v,也就是最后一次迭代都结束后,此时i=n+1,a[1:n]中都没有出现过v,程序会返回NIL,符合要求。
#define NIL -1
int find(int a[], int n, int key)
{
for(int i = 1; i <= n; ++i)
if(a[i] == key) return i;
return NIL;
}
2.1-4
输入:
a
=
(
a
n
,
a
n
−
1
,
.
.
.
a
2
,
a
1
)
2
,
b
=
(
b
n
,
b
n
−
1
,
.
.
.
b
2
,
b
1
)
2
a = (a_{n}, a_{n-1}, ...a_2, a_1)_2, b = (b_{n}, b_{n-1}, ...b_2, b_1)_2
a=(an,an−1,...a2,a1)2,b=(bn,bn−1,...b2,b1)2
输出:答案
C
,
C
=
(
a
+
b
)
2
C, C = (a + b)_2
C,C=(a+b)2
按位取模和加就可以了,竖式计算吧。
void add(int a[], int b[], int n, int c[])
{
for(int i = 1; i <= n; ++i) c[i] ^= a[i] ^ b[i], c[i + 1] = a[i] && b[i];
}