数据结构习题1-4
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
这里只需要一个辅助空间temp.
21
2-8
在单链表类SLIST中添加一个成员函数,将单 链表中元素的次序完全颠倒。
22
单链表是线性表的一种链接存储方式,其结点
结构:
data next
每个结点只含一个链接域的链表叫单链表。
d1
d2
head 带有哨位结点的单链表
d3
tail
23
方法1:类似于习题2-1,将第i个与第n-i+1个 结点的数据域互换。指针p1和p2向中间移动, 更换数据域的取值。
比较为基本运算
最好:空,元素都大于maxk(找不到)//O(1) 最坏:元素都小于mink(找不到)
元素都小于maxk //O(n)
30
算法 LD ( L,mink,maxk. L)
LD1.[特殊情况] IF mink maxk THEN (RETURN.) IF (next(head)=NULL) THEN RETURN.
= 5(k+1)/3-2
综上,命题得证。
16
第二章习题
17
2-1
编写算法Reverse (A[ ], n),将顺序存储的线性表 A=( a1, a2, …, an )转换为A=( an,…, a2, a1),要求 转换过程中使用尽量少的辅助空间。
线性表有两种存储方式:顺序存储、链接存储
按照线性表结点间的逻辑顺序依次将它们存储于一 组地址连续的存储单元中。 一维数组是实现线性表顺序存储的有效方法。 如线性表(a1, a2, …, an),可用一维数组a[n]存放。
10 51
12
7
51
3
s helpStack
51 3 7 10 12 51 s helpStack
所有值大于mink且小于maxk的元素,同时释放被 删结点空间,并分析算法的时间复杂度。
特殊情况的处理:
1. 表为空 2. 元素都大于maxk 3. 元素都小于mink
第一个元素大于maxk 最后一个元素小于mink
29
主要思想:
找到大于mink的第一个元素,删除操作,直至元 素大于maxk。 时间复杂度:
q ←p. p ←next(p).
AVAILq.)
) RETURN.
prev
p
32
LD3.[找]
WHILE(pNULL AND data(p)<maxk) DO
( IF(data(p)mink) THEN
(prev ←p. p ←next(p)) //向后移动
ELSE( //删除
next(prev) ←next(p).
BS (A, mid1, j. hmax, hmin). BS4. [合并]
fmax max{gmax, hmax}. fmin min{gmin, hmin}.
13
算法 BS 递归方法
分治思想:不断将规模变小,直至可以处理 (本题是2或1个元素),之后进行合并。
如果规定基本运算为元素的比较,则
18
a1 a2 … an-1 an an an-1 … a2 a1
辅助数组B: 先将A[1]存到B[n], A[2]存到B[n-1],…
A[n]存到B[1]; 之后将B赋值给A。
辅助空间大小为n 题目要求用尽量少的辅助空间
19
分析
a1 a2
… an-1 an
an an-1 … a2 a1
1+n 2+(n-1) … (n-1)+2 n+1
THEN (flag←false. RETURN.)
i←i+1.
)▌
10
参考答案3
算法 S (n. flag)
S1[n≤1?]
IF (n≤1) THEN (flag←false. RETURN.)
S2[初始化] i←2. flag←true.
S3[求余判断]
时间复杂性
最好为:O(1) 最坏情况为:O(n1/2)
所以:T((k+1)/2 )≤5((k+1)/2)/3-2 , (1) T((k+1)/2 )≤5((k+1)/2 )/3-2 (2)
T(k+1)= T((k+1)/2 )+T((k+1)/2)+2
≤ [5((k+1)/2)/3-2]+[5((k+1)/2 )/3-2]+2
= 5((k+1)/2 + (k+1)/2 )/3-2 //k+1= (k+1)/2 + (k+1)/2
0
n=1
T(n) = 1
n=2
T( n/2 )+T( n/2 )+2 n>2
14
数学归纳法:
① 基础归纳:n=c (初值)时,命题是正确的; ② 归纳步骤:假设n=k时,命题成立,证明n
=k+1时,命题也成立。 完成情况:
1. 利用16页结论T(n)=3n/2-2,需要注意 前提条件——当n是2的幂时 ;
head
p1
p2
…
方法2:遍历链表的同时修改指针。 方法3:使用堆栈,实现单链表求逆。
24
方法2
思想:从左向右,依次更换邻近结点的指针方向。
初始设置,第一个元素需要被放到表尾,指向空指 针,p1=null,p2=next(head) //第一个元素
head
p2 2
p3 3
p1
1
4
P3 next(p2) next(P2) P1 //反转
4
1-5
试用ADL语言编写一个算法,判断任一 整数 n 是否为素数。
素数: 大于1的自然数中,除了1和此整数 自身外,不能被其他自然数整除的数。
判断:对于指定的n,如果[2,n-1]内 的整数都不能整除n,则n为素数。
5
算<步法骤<算名>法.名[说>明(变] 量i1,…,变量im. 变量j1,…,变量jn)
7
算法 S (n. flag)
/*判断整数n是否为素数,结果保存到变量flag*/
S1[n≤1?]
IF (n≤1) THEN (flag←false. RETURN.)
S2[初始化] i←2. flag←true.
S3[求余判断] WHILE (i≤n-1) DO
时间复杂性:
最好为:O(1) 最坏情况为:O(n)
22
考察知识点
算法的时间复杂度
最好 平均 最坏
计算时间复杂度的一般步骤
确定基本运算 (基本运算指算法运行过程中起主 要作用花费最多时间的运算)
确定时间复杂度 用渐进表示法表示
3
参考答案
以乘法为基本运算, 最坏时间复杂度为T(n)=n(n+1)/2, 渐近表示法O(n2) (或算法是n2 阶的)
P1 P2. P2 P3.
25
参考答案
算法 Reverse ( head. head)
/*将指针 head 所指向的链表倒置*/ RV1[空链表]
IF(next(head)=NULL) RETURN. RV2[指针初始化]
//P1,P2 分别指向两个连续的节点 P1 NULL. P2 next(head).
26
p1 p2
p3
RV3[反转链表]
WHILE( P2 ≠ NULL ) DO
(
P3 next(p2)
next(P2) P1.
//反转节点指针
P1 P2. P2 P3. //移动3个指针
)
RV4[head指向反转链表]
next(head) P1 . ▌
27
p1
p2
RV3[反转链表]
WHILE( P2 ≠ NULL ) DO
9
参考答案2
算法 S (n. flag)
S1[n≤1?]
IF (n≤1) THEN (flag←false. RETURN.)
S2[初始化] i←2. flag←true.
S3[求余判断]
时间复杂性:
最好为:O(1) 最坏情况为:O(n)
WHILE (i ≤ n/2 ) DO
( IF (n MOD i)=0
小元素,已知 i j; 假定A 中元素互异 */ BS1. [递归出口] IF i j THEN (fmax fmin A[i]. RETURN.) IF i j 1 THEN
(IF A[i] A[j] THEN(fmax A[j]. fmin A[i]). ELSE (fmax A[i]. fmin A[j]). RETURN). BS2. [取中值] mid (ij)/2 BS3. [递归调用] BS (A, i, mid. gmax, gmin).
( IF (n MOD i)=0
THEN (flag←false. RETURN.)
i←i+1 .
)▌
8
边界条件和特殊数据,人工模拟算法执行过程
正确性验证: 假定n=7,模拟执行过程,对i=2,3,4, 5,6时,分别判断(7 mod i)的取值是否为 0改。进:n-1?a…≤a…n,n…1a/=n2,a,a1…≥n/b21≥nb/2b2=,,nn…ba1/,≤2/…2,bnnb//2…2,, …
只需从线性表的第一个数据元素开始,将 第i个数据元素与第n-i+1个数据元素相交 换即可。
i的变化范围是1到n/2。
20
参考答案
算法Reverse(A, n. A) Reverse1. [元素互换]
FOR i=1 TO n/2 DO ( temp ← A[i]. A[i] ← A[n-i+1]. A[n-i+1] ← temp. ).▌
<操作1>
…
ADL语言书写
<操作J>
算法的格式
….
▌
算术运算符: +,-,*,/, MOD(模),DIV(除数),/(除),
, 关系、逻辑运算符、逻辑常量、集合运算符 赋值语句: 条件语句: if then else ;
for i=1 to n step 1 EXIT语句、RETURN语句 、输入、输出语句
WHILE (i ≤ 「n 1/2 ) DO
( IF (n MOD i)=0
THEN (flag←false. RETURN.)
i←i+1.
)▌
11
1-11
证明对正整数n≥3,算法BS的元素比较 次数T(n)≤5n/3-2。
12
算法BS(A , i , j . fmax , fmin) /* 在数组 A 的第 i 至第 j 个元素间寻找最大和最
2. 由n=k反推n=k-1时的情况。
15
0
n=1
T(n) = 1
n=2
T( n/2 )+T( n/2 )+2 n>2
n=3 时, T(3)=T(1)+T(2)+2=3,53/3-2=3,命题成立。 假设n<=k时命题成立,需证明n=k+1时成立。
当k≥3时,有(k+1)> (k+1)/2 ≥ (k+1)/2 , 即k≥ (k+1)/2 ≥ (k+1)/2
第一章习题
1
课后作业
求下述计算f=1!+2!+3!+…+n!的算法的时间复杂性。
void factorsum(int n) { int i, j;
int f, w; f=0; for (i=1;i<=n; i++) { w=1;
for (j=1; j<=i; j++) w=w*j;
f= f + w; } return; }
(
P3 next(p2)
next(P2) P1.
//反转节点指针
P1 P2. P2 P3. //移动3个指针
)
RV4[head指向反转链表]
next(head) P1 . ▌
28
2-11
链表有序的 找到区间
已知线性表中的元素以data值递增有序排列,并以 单链表做存储结构。试写一高效的算法,删除表中
34
基本思想: 取栈顶元素,若不匹配,则进行弹栈操作; 找到(或无法找到)后恢复原来的元素次 序。
关键点:记录弹出的顺序,后弹出的元素能 够先被压回原来的栈 ,因此需要使用一个辅 助堆栈。
35
从使用的角度来讲,链式堆栈与顺序堆栈没有区别。
3 7 51 10 12 51 s helpStack
LD2.[初始化] prev←head. p ←next(head) prev
head
P
31
ቤተ መጻሕፍቲ ባይዱ LD3.[找]
WHILE(pNULL AND data(p)<maxk) DO
( IF(data(p)mink) THEN
(prev ←p. p ←next(p)) //向后移动
ELSE( //删除
next(prev) ←next(p).
6
完成情况
① 思想:基本正确 ② 算法:
特殊情况处理——n1?算法输出; ADL语言的使用——
a) 运算符号: % ?sqrt ? fabs() ? b) 输入输出参数: 设置返回值;中间用“.”分隔。 c) 条件语句:
if then else ; for i=1 to n step 1 (i=i+1?) d) 赋值语句:
q ←p. p ←next(p).
AVAILq.)
) RETURN. q
p
prev
33
2-17
对于顺序堆栈和链式堆栈s,分别编写函数 SelectItem(Stack & s , int n),要求在 堆栈中查找元素n在栈中第一次出现的位置, 并将该位置元素移至栈顶,同时其他元素次 序不变。(注意:用int匹配堆栈的模板)
21
2-8
在单链表类SLIST中添加一个成员函数,将单 链表中元素的次序完全颠倒。
22
单链表是线性表的一种链接存储方式,其结点
结构:
data next
每个结点只含一个链接域的链表叫单链表。
d1
d2
head 带有哨位结点的单链表
d3
tail
23
方法1:类似于习题2-1,将第i个与第n-i+1个 结点的数据域互换。指针p1和p2向中间移动, 更换数据域的取值。
比较为基本运算
最好:空,元素都大于maxk(找不到)//O(1) 最坏:元素都小于mink(找不到)
元素都小于maxk //O(n)
30
算法 LD ( L,mink,maxk. L)
LD1.[特殊情况] IF mink maxk THEN (RETURN.) IF (next(head)=NULL) THEN RETURN.
= 5(k+1)/3-2
综上,命题得证。
16
第二章习题
17
2-1
编写算法Reverse (A[ ], n),将顺序存储的线性表 A=( a1, a2, …, an )转换为A=( an,…, a2, a1),要求 转换过程中使用尽量少的辅助空间。
线性表有两种存储方式:顺序存储、链接存储
按照线性表结点间的逻辑顺序依次将它们存储于一 组地址连续的存储单元中。 一维数组是实现线性表顺序存储的有效方法。 如线性表(a1, a2, …, an),可用一维数组a[n]存放。
10 51
12
7
51
3
s helpStack
51 3 7 10 12 51 s helpStack
所有值大于mink且小于maxk的元素,同时释放被 删结点空间,并分析算法的时间复杂度。
特殊情况的处理:
1. 表为空 2. 元素都大于maxk 3. 元素都小于mink
第一个元素大于maxk 最后一个元素小于mink
29
主要思想:
找到大于mink的第一个元素,删除操作,直至元 素大于maxk。 时间复杂度:
q ←p. p ←next(p).
AVAILq.)
) RETURN.
prev
p
32
LD3.[找]
WHILE(pNULL AND data(p)<maxk) DO
( IF(data(p)mink) THEN
(prev ←p. p ←next(p)) //向后移动
ELSE( //删除
next(prev) ←next(p).
BS (A, mid1, j. hmax, hmin). BS4. [合并]
fmax max{gmax, hmax}. fmin min{gmin, hmin}.
13
算法 BS 递归方法
分治思想:不断将规模变小,直至可以处理 (本题是2或1个元素),之后进行合并。
如果规定基本运算为元素的比较,则
18
a1 a2 … an-1 an an an-1 … a2 a1
辅助数组B: 先将A[1]存到B[n], A[2]存到B[n-1],…
A[n]存到B[1]; 之后将B赋值给A。
辅助空间大小为n 题目要求用尽量少的辅助空间
19
分析
a1 a2
… an-1 an
an an-1 … a2 a1
1+n 2+(n-1) … (n-1)+2 n+1
THEN (flag←false. RETURN.)
i←i+1.
)▌
10
参考答案3
算法 S (n. flag)
S1[n≤1?]
IF (n≤1) THEN (flag←false. RETURN.)
S2[初始化] i←2. flag←true.
S3[求余判断]
时间复杂性
最好为:O(1) 最坏情况为:O(n1/2)
所以:T((k+1)/2 )≤5((k+1)/2)/3-2 , (1) T((k+1)/2 )≤5((k+1)/2 )/3-2 (2)
T(k+1)= T((k+1)/2 )+T((k+1)/2)+2
≤ [5((k+1)/2)/3-2]+[5((k+1)/2 )/3-2]+2
= 5((k+1)/2 + (k+1)/2 )/3-2 //k+1= (k+1)/2 + (k+1)/2
0
n=1
T(n) = 1
n=2
T( n/2 )+T( n/2 )+2 n>2
14
数学归纳法:
① 基础归纳:n=c (初值)时,命题是正确的; ② 归纳步骤:假设n=k时,命题成立,证明n
=k+1时,命题也成立。 完成情况:
1. 利用16页结论T(n)=3n/2-2,需要注意 前提条件——当n是2的幂时 ;
head
p1
p2
…
方法2:遍历链表的同时修改指针。 方法3:使用堆栈,实现单链表求逆。
24
方法2
思想:从左向右,依次更换邻近结点的指针方向。
初始设置,第一个元素需要被放到表尾,指向空指 针,p1=null,p2=next(head) //第一个元素
head
p2 2
p3 3
p1
1
4
P3 next(p2) next(P2) P1 //反转
4
1-5
试用ADL语言编写一个算法,判断任一 整数 n 是否为素数。
素数: 大于1的自然数中,除了1和此整数 自身外,不能被其他自然数整除的数。
判断:对于指定的n,如果[2,n-1]内 的整数都不能整除n,则n为素数。
5
算<步法骤<算名>法.名[说>明(变] 量i1,…,变量im. 变量j1,…,变量jn)
7
算法 S (n. flag)
/*判断整数n是否为素数,结果保存到变量flag*/
S1[n≤1?]
IF (n≤1) THEN (flag←false. RETURN.)
S2[初始化] i←2. flag←true.
S3[求余判断] WHILE (i≤n-1) DO
时间复杂性:
最好为:O(1) 最坏情况为:O(n)
22
考察知识点
算法的时间复杂度
最好 平均 最坏
计算时间复杂度的一般步骤
确定基本运算 (基本运算指算法运行过程中起主 要作用花费最多时间的运算)
确定时间复杂度 用渐进表示法表示
3
参考答案
以乘法为基本运算, 最坏时间复杂度为T(n)=n(n+1)/2, 渐近表示法O(n2) (或算法是n2 阶的)
P1 P2. P2 P3.
25
参考答案
算法 Reverse ( head. head)
/*将指针 head 所指向的链表倒置*/ RV1[空链表]
IF(next(head)=NULL) RETURN. RV2[指针初始化]
//P1,P2 分别指向两个连续的节点 P1 NULL. P2 next(head).
26
p1 p2
p3
RV3[反转链表]
WHILE( P2 ≠ NULL ) DO
(
P3 next(p2)
next(P2) P1.
//反转节点指针
P1 P2. P2 P3. //移动3个指针
)
RV4[head指向反转链表]
next(head) P1 . ▌
27
p1
p2
RV3[反转链表]
WHILE( P2 ≠ NULL ) DO
9
参考答案2
算法 S (n. flag)
S1[n≤1?]
IF (n≤1) THEN (flag←false. RETURN.)
S2[初始化] i←2. flag←true.
S3[求余判断]
时间复杂性:
最好为:O(1) 最坏情况为:O(n)
WHILE (i ≤ n/2 ) DO
( IF (n MOD i)=0
小元素,已知 i j; 假定A 中元素互异 */ BS1. [递归出口] IF i j THEN (fmax fmin A[i]. RETURN.) IF i j 1 THEN
(IF A[i] A[j] THEN(fmax A[j]. fmin A[i]). ELSE (fmax A[i]. fmin A[j]). RETURN). BS2. [取中值] mid (ij)/2 BS3. [递归调用] BS (A, i, mid. gmax, gmin).
( IF (n MOD i)=0
THEN (flag←false. RETURN.)
i←i+1 .
)▌
8
边界条件和特殊数据,人工模拟算法执行过程
正确性验证: 假定n=7,模拟执行过程,对i=2,3,4, 5,6时,分别判断(7 mod i)的取值是否为 0改。进:n-1?a…≤a…n,n…1a/=n2,a,a1…≥n/b21≥nb/2b2=,,nn…ba1/,≤2/…2,bnnb//2…2,, …
只需从线性表的第一个数据元素开始,将 第i个数据元素与第n-i+1个数据元素相交 换即可。
i的变化范围是1到n/2。
20
参考答案
算法Reverse(A, n. A) Reverse1. [元素互换]
FOR i=1 TO n/2 DO ( temp ← A[i]. A[i] ← A[n-i+1]. A[n-i+1] ← temp. ).▌
<操作1>
…
ADL语言书写
<操作J>
算法的格式
….
▌
算术运算符: +,-,*,/, MOD(模),DIV(除数),/(除),
, 关系、逻辑运算符、逻辑常量、集合运算符 赋值语句: 条件语句: if then else ;
for i=1 to n step 1 EXIT语句、RETURN语句 、输入、输出语句
WHILE (i ≤ 「n 1/2 ) DO
( IF (n MOD i)=0
THEN (flag←false. RETURN.)
i←i+1.
)▌
11
1-11
证明对正整数n≥3,算法BS的元素比较 次数T(n)≤5n/3-2。
12
算法BS(A , i , j . fmax , fmin) /* 在数组 A 的第 i 至第 j 个元素间寻找最大和最
2. 由n=k反推n=k-1时的情况。
15
0
n=1
T(n) = 1
n=2
T( n/2 )+T( n/2 )+2 n>2
n=3 时, T(3)=T(1)+T(2)+2=3,53/3-2=3,命题成立。 假设n<=k时命题成立,需证明n=k+1时成立。
当k≥3时,有(k+1)> (k+1)/2 ≥ (k+1)/2 , 即k≥ (k+1)/2 ≥ (k+1)/2
第一章习题
1
课后作业
求下述计算f=1!+2!+3!+…+n!的算法的时间复杂性。
void factorsum(int n) { int i, j;
int f, w; f=0; for (i=1;i<=n; i++) { w=1;
for (j=1; j<=i; j++) w=w*j;
f= f + w; } return; }
(
P3 next(p2)
next(P2) P1.
//反转节点指针
P1 P2. P2 P3. //移动3个指针
)
RV4[head指向反转链表]
next(head) P1 . ▌
28
2-11
链表有序的 找到区间
已知线性表中的元素以data值递增有序排列,并以 单链表做存储结构。试写一高效的算法,删除表中
34
基本思想: 取栈顶元素,若不匹配,则进行弹栈操作; 找到(或无法找到)后恢复原来的元素次 序。
关键点:记录弹出的顺序,后弹出的元素能 够先被压回原来的栈 ,因此需要使用一个辅 助堆栈。
35
从使用的角度来讲,链式堆栈与顺序堆栈没有区别。
3 7 51 10 12 51 s helpStack
LD2.[初始化] prev←head. p ←next(head) prev
head
P
31
ቤተ መጻሕፍቲ ባይዱ LD3.[找]
WHILE(pNULL AND data(p)<maxk) DO
( IF(data(p)mink) THEN
(prev ←p. p ←next(p)) //向后移动
ELSE( //删除
next(prev) ←next(p).
6
完成情况
① 思想:基本正确 ② 算法:
特殊情况处理——n1?算法输出; ADL语言的使用——
a) 运算符号: % ?sqrt ? fabs() ? b) 输入输出参数: 设置返回值;中间用“.”分隔。 c) 条件语句:
if then else ; for i=1 to n step 1 (i=i+1?) d) 赋值语句:
q ←p. p ←next(p).
AVAILq.)
) RETURN. q
p
prev
33
2-17
对于顺序堆栈和链式堆栈s,分别编写函数 SelectItem(Stack & s , int n),要求在 堆栈中查找元素n在栈中第一次出现的位置, 并将该位置元素移至栈顶,同时其他元素次 序不变。(注意:用int匹配堆栈的模板)