第2章算法答案
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
表结束。
算法:
proc ds0208(var h:pointer);
{ h:带头结点的单链表的头指针,}
p:=h^.next;
while p^.next<>nil do
if p^.data=p^.next^.data
then [u:=p; p:=p^.next; dispose(u) ] { 删除相同值的结点}
ha:=ha^.next;
p^.next:=hb;
hb:=p; ]
end; {ds0209_2}
2.10
设有两个按元素值递增有序排列的线性表A和B, 均以单链表作存储结构, 写一算
法将A表和B表归并成一个按元素值递增有序排列(允许值相同)的线性表C.
设计思想:
(1) 当A表和B表都不空时, 进行比较, 将较小数链入C表表尾, 以保证其递增性;
{ 沿较短的链表查找至链表尾端}
{当p^.next 不空, p后移, 找到此链表中的最后一个结点}
p^.next := q
{两链表链接上)
end; {ds0206}
2.7
已知线性表中的元素按值递增排列, 并以单链表作存储结构. 写一高效算法, 删除表中所有值大于mink
且小于maxk的元素(若表中存在这样的元素)。
while (pa<>nil) and (pb<>nil) do {A,B表不空}
[ if pa^.data<=pb^.data
then [s:=pa; pa:=pa^.next ]
else [s:=pb; pb:=pb^.next ];
rc^.next:=s; rc:=s
]
if pa=nil thenห้องสมุดไป่ตู้rc^.next:=pb
]
while pb<>nil do
[ s:=pb; pb:=pb^.next;
s^.next:=hc^.next; hc^.next:=s
]
endp;{ds02011}
2.12
已知A、B和C为以链表存储的三个递增有序的线性表,对A作如下运算:删除那些在B中出现又在C中出现的元素。
设计思想
从A表中取出每一个元素p^.data,检查是否出现在B表和C表中,是,则删除P。
两个链表接在一起, 并要求以尽可能短的时间完成。
设计思想:
(1) 比较ha和hb两链表, 找较短链;
(2) 沿较短链找到最后一个结点;
(3) 将两链连接上。
算法:
proc ds0206(var hc:pointer; ha,hb:pointer);
{ ha,hb,hc:带头结点的单链表的头指针,其中hc是新生成的)
{当pc不空时,找等于x的结点pb}
if (pb<>nil)and (pb^.data=x)and(pc<>nil)and (pc^.data=x)
(2) 插入到新链表(an,...,a1序)的表头处
(3) 重复(1)和(2)步, 直到原链表空止。
算法:
proc ds0209_2(var ha,hb:pointer);
{ ha,hb:单链表的头指针}
hb:=nil; {新链表置初值}
while ha<>nil do {原表不空,执行}
[ p:=ha;
(2) 若一线性表结束,将另一线性表存于vc。
算法:
PROC ds0203(va,vb:sqlisttp;VAR vc:sqlisttp);
i:=1;j:=1;k:=0; {指针初始化}
WHILE (i<=va.last) AND (j<=vb.last) DO {归并}
IF va.elem[i]<=vb.elem[j]
while pa<>nil do {A表不空}
[ x:=pa^.data;
while (pb<>nil)and (pb^.data<>x) do pb:=pb^.next
{当pb不空时,找等于x的结点pb}
while (pc<>nil)and (pc^.data<>x) do pc:=pc^.next
的算法
一. 设计思想:
用x与每一元素结点的数据域的值进行比较,若等于x,表示查找成功,否则,查找失败。
算法:
proc ds0205_1(ha:pointer; x:datatype);
{ ha:带头结点的单链表的头指针}
p:=ha^.next; {p:指向第一个元素结点}
while (p<>nil) cand p^.data<>x do p:=p^.next;
(2) 若某一链表空, 将另一链表接在C表之后。
算法:
proc ds0210(var hc:pointer; ha,hb:pointer);
{ ha,hb,hc分别为A链.B链和C链的头指针}
pa:ha; pb:=hb;
new(hc); rc:=hc; {生成新链表的头结点, hc:头指针, rc:尾指针}
else rc^.next:=pa;
endp; {ds0210}
2.11
设有两个按元素值递增有序排列的线性表A和B, 均以单链表作存储结构, 写一
算法将A表和B表归并成一个按元素值非递增有序排列(允许值相同)的线性表C.
设计思想
(1) 当A表和B表都不空时, 进行比较, 将较小数插入C表表首, 以保证其递减性;
[a[i+1]:=a[i]; i:=i-1 ]; {查找插入位置, 并后移}
a[i+1]:=x;
elenum:=elenum+1
]
endp; {ds0201}
2.2
已知线性表存于a[1..array]中的前last个分量中,删除从第i个元素起的k个元素。
设计思想:
将k个元素一次删除,即从i+k开始,每一元素前移k个元素位置。
a[j-k]:=a[j]; {前移k个元素}
last:=last-k; {表长-k}
]
else error('入口参数错误')
endp; {ds0202}
2.3
已知两个线性表va和vb,且顺序存储,其值递增排列,要求将它们归并成一个新的有序表vc。
设计思想:
(1) 当线性表va和线性表vb均未结束时,比较,将较小数存于线性表vc;
算法:
proc ds0209_1(a:array [1..n] of elemtp; n:integer);
{ a:顺序存储的线性表, 表中有n个数据元素}
for i:=1 to n div 2 do
a[i]←→a[n-i+1];
end; {ds0209_1}
二. 以链表为存储结构:
设计思想:
(1) 取出原链表(a1,...an序)中的一结点
{当p不空并且p^.data不等于x时, p后移}
return(p); {成功: p<>nil ; 失败:p=nil}
end; {ds0205_1}
二. 设计思想:
逐一访问每一结点并计数, 即可得此链表的长度。
算法:
proc ds0205_2(ha:pointer; x:datatype);
{ ha:带头结点的单链表的头指针}
算法:
proc ds0202(var a:array[1..size] of integer; var last:integer; i,k:integer);
if (k>=0)and(1<=i+k<=last)and(0<=last<=array)
then [ for j:=i+k to last do
pc:=ha; {hc:新生成的链表的头指针, 利用原空间}
if ha^.data < hb^.data
then [ p:=ha; q:=hb^.next ]
else [ p:=hb; q:=ha^.next ]
{ p指向较短链, q指向较长链}
while (p^.next<>nil) do p:=p^.next;
设计思想:
(1) 从第一个结点开始找其值>minK的结点p(它的前趋结点为q);
(2) 保存q, 从p开始找所有值<=maxk的结点, 并删除每个这样的p结点;
(3) q^.next指向p。
算法:
proc ds0207(var h:pointer; mink,maxk:integer);
{ h:带头结点的单链表的头指针,}
[ if pa^.data<=pb^.data
then [s:=pa; pa:=pa^.next ]
else [s:=pb; pb:=pb^.next ];
s^.next:=hc^.next; hc^.next:=s
]
while pa<>nil do
[ s:=pa; pa:=pa^.next ;
s^.next:=hc^.next; hc^.next:=s
{ 删除所有的其值>mink并且<maxk的结点p}
q.next:=p
endp; {ds0207}
2.8
已知线性表中的元素按值递增排列, 并以单链表作存储结构. 写一高效算法, 删除表中的多余元素, 使得运算后的线性表中所有元素的值均不相同。
设计思想:
从第一个结点开始, 每一结点的值与后一结点的值作比较 , 若相等, 则删除后一结点, 直至整个链
p:=ha; {p:指向头结点}
len:=0;
while (p^.next<>nil) do [ p:=p^.next; len:=len+1]
{当p不空x时, 访问其结点, 并计数}
return(len);
{len:即为此链表的长度)
end; {ds0205_2}
2.6
已知ha和hb分别指向两个单链表的头结点, 且头结点的数据域(整型)中存放链表的长度, 写一算法将这
else [ q:=p; p:=p^.next ]; {p后移}
endp; {ds0208}
2.9
以一维数组和链表作存储结构, 实现线性表就地逆置的算法, 即将线性表
(a1,a2,...an)==>(an,...,a2,a1)
一. 以一维数组为存储结构:
设计思想:
用a[1]与a[n]交换,a[2]与a[n-1]交换,……,以此类推,直至n div 2止。
(2) 若某一链表空, 将另一链表剩余部分依次插入在C表的表首。
算法:
proc ds02011(var hc:pointer; ha,hb:pointer);
{ ha,hb,hc分别为A链.B链和C链的头指针}
pa:=ha; pb:=hb;
new(hc); {生成新链表的头结点}
while (pa<>nil) and (pb<>nil) do {A,B表不空}
算法:
proc ds0201(var a:array[1..size] of integer; var elenum:integer; x:integer);
if elenum=size then error('array overflow')
else [ i:=elenum;
while (i>=1) cand (x<a[i]) do
q:=h; p:=h^.next;
while (p<>nil) and (p^.data<=mink) do
[ q:=p; p:=p^.next ];
{p:其值>mink的结点, q是p的前趋}
while (p<>nil) and (p^.data<maxk) do
[ u:=p; p:=p^.next; dispose(p) ];
注意:应保留p的前趋
算法:
proc ds02012(var ha:pointer; hb,hc:pointer);
{ ha,hb,hc分别为A链.B链和C链的头指针}
pre:=ha; pa:=ha^.next; {pre:pa的前趋}
pb:=hb^.next;
pc:=hc^.next; {pb,pc:总指向hb,hc链的最后一个已考查的结点}
THEN [vc.elem[k+1]:=va.elem[i];k:=k+1;i:=i+1]
ELSE [vc.elem[k+1]:=vb.elem[j];k:=k+1;j:=j+1];
WHILE i<=va.last DO {插入VA的剩余段}
[vc.elem[k+1]:=va.elem[i];k:=k+1;i:=i+1];
2.1
设线性表存于a[1..arrsize]的前elenum个分量中, 且递增有序. 试写一算法,将x插入到线性表的适当位置, 以保持线性表的有序性。
设计思想:
(1) 先查找 x 的插入位置 i ;
(2) 将线性表中自A[i]至A[elenum]的元素后移一个位置;
(3) 最后将x查入到A[i]中, 并且将表长加1。
WHILE j<=vb.last DO {插入VB的剩余段}
[vc.elem[k+1]:=vb.elem[j];k:=k+1;j:=j+1];
vc.last:=k {K为VC中元素个数}
ENDP;{ds0203}
2.5
写出在带头结点的动态单链表结构上实现线性表操作
一. LOCATE(L,X)
二. LENGTH(L)
算法:
proc ds0208(var h:pointer);
{ h:带头结点的单链表的头指针,}
p:=h^.next;
while p^.next<>nil do
if p^.data=p^.next^.data
then [u:=p; p:=p^.next; dispose(u) ] { 删除相同值的结点}
ha:=ha^.next;
p^.next:=hb;
hb:=p; ]
end; {ds0209_2}
2.10
设有两个按元素值递增有序排列的线性表A和B, 均以单链表作存储结构, 写一算
法将A表和B表归并成一个按元素值递增有序排列(允许值相同)的线性表C.
设计思想:
(1) 当A表和B表都不空时, 进行比较, 将较小数链入C表表尾, 以保证其递增性;
{ 沿较短的链表查找至链表尾端}
{当p^.next 不空, p后移, 找到此链表中的最后一个结点}
p^.next := q
{两链表链接上)
end; {ds0206}
2.7
已知线性表中的元素按值递增排列, 并以单链表作存储结构. 写一高效算法, 删除表中所有值大于mink
且小于maxk的元素(若表中存在这样的元素)。
while (pa<>nil) and (pb<>nil) do {A,B表不空}
[ if pa^.data<=pb^.data
then [s:=pa; pa:=pa^.next ]
else [s:=pb; pb:=pb^.next ];
rc^.next:=s; rc:=s
]
if pa=nil thenห้องสมุดไป่ตู้rc^.next:=pb
]
while pb<>nil do
[ s:=pb; pb:=pb^.next;
s^.next:=hc^.next; hc^.next:=s
]
endp;{ds02011}
2.12
已知A、B和C为以链表存储的三个递增有序的线性表,对A作如下运算:删除那些在B中出现又在C中出现的元素。
设计思想
从A表中取出每一个元素p^.data,检查是否出现在B表和C表中,是,则删除P。
两个链表接在一起, 并要求以尽可能短的时间完成。
设计思想:
(1) 比较ha和hb两链表, 找较短链;
(2) 沿较短链找到最后一个结点;
(3) 将两链连接上。
算法:
proc ds0206(var hc:pointer; ha,hb:pointer);
{ ha,hb,hc:带头结点的单链表的头指针,其中hc是新生成的)
{当pc不空时,找等于x的结点pb}
if (pb<>nil)and (pb^.data=x)and(pc<>nil)and (pc^.data=x)
(2) 插入到新链表(an,...,a1序)的表头处
(3) 重复(1)和(2)步, 直到原链表空止。
算法:
proc ds0209_2(var ha,hb:pointer);
{ ha,hb:单链表的头指针}
hb:=nil; {新链表置初值}
while ha<>nil do {原表不空,执行}
[ p:=ha;
(2) 若一线性表结束,将另一线性表存于vc。
算法:
PROC ds0203(va,vb:sqlisttp;VAR vc:sqlisttp);
i:=1;j:=1;k:=0; {指针初始化}
WHILE (i<=va.last) AND (j<=vb.last) DO {归并}
IF va.elem[i]<=vb.elem[j]
while pa<>nil do {A表不空}
[ x:=pa^.data;
while (pb<>nil)and (pb^.data<>x) do pb:=pb^.next
{当pb不空时,找等于x的结点pb}
while (pc<>nil)and (pc^.data<>x) do pc:=pc^.next
的算法
一. 设计思想:
用x与每一元素结点的数据域的值进行比较,若等于x,表示查找成功,否则,查找失败。
算法:
proc ds0205_1(ha:pointer; x:datatype);
{ ha:带头结点的单链表的头指针}
p:=ha^.next; {p:指向第一个元素结点}
while (p<>nil) cand p^.data<>x do p:=p^.next;
(2) 若某一链表空, 将另一链表接在C表之后。
算法:
proc ds0210(var hc:pointer; ha,hb:pointer);
{ ha,hb,hc分别为A链.B链和C链的头指针}
pa:ha; pb:=hb;
new(hc); rc:=hc; {生成新链表的头结点, hc:头指针, rc:尾指针}
else rc^.next:=pa;
endp; {ds0210}
2.11
设有两个按元素值递增有序排列的线性表A和B, 均以单链表作存储结构, 写一
算法将A表和B表归并成一个按元素值非递增有序排列(允许值相同)的线性表C.
设计思想
(1) 当A表和B表都不空时, 进行比较, 将较小数插入C表表首, 以保证其递减性;
[a[i+1]:=a[i]; i:=i-1 ]; {查找插入位置, 并后移}
a[i+1]:=x;
elenum:=elenum+1
]
endp; {ds0201}
2.2
已知线性表存于a[1..array]中的前last个分量中,删除从第i个元素起的k个元素。
设计思想:
将k个元素一次删除,即从i+k开始,每一元素前移k个元素位置。
a[j-k]:=a[j]; {前移k个元素}
last:=last-k; {表长-k}
]
else error('入口参数错误')
endp; {ds0202}
2.3
已知两个线性表va和vb,且顺序存储,其值递增排列,要求将它们归并成一个新的有序表vc。
设计思想:
(1) 当线性表va和线性表vb均未结束时,比较,将较小数存于线性表vc;
算法:
proc ds0209_1(a:array [1..n] of elemtp; n:integer);
{ a:顺序存储的线性表, 表中有n个数据元素}
for i:=1 to n div 2 do
a[i]←→a[n-i+1];
end; {ds0209_1}
二. 以链表为存储结构:
设计思想:
(1) 取出原链表(a1,...an序)中的一结点
{当p不空并且p^.data不等于x时, p后移}
return(p); {成功: p<>nil ; 失败:p=nil}
end; {ds0205_1}
二. 设计思想:
逐一访问每一结点并计数, 即可得此链表的长度。
算法:
proc ds0205_2(ha:pointer; x:datatype);
{ ha:带头结点的单链表的头指针}
算法:
proc ds0202(var a:array[1..size] of integer; var last:integer; i,k:integer);
if (k>=0)and(1<=i+k<=last)and(0<=last<=array)
then [ for j:=i+k to last do
pc:=ha; {hc:新生成的链表的头指针, 利用原空间}
if ha^.data < hb^.data
then [ p:=ha; q:=hb^.next ]
else [ p:=hb; q:=ha^.next ]
{ p指向较短链, q指向较长链}
while (p^.next<>nil) do p:=p^.next;
设计思想:
(1) 从第一个结点开始找其值>minK的结点p(它的前趋结点为q);
(2) 保存q, 从p开始找所有值<=maxk的结点, 并删除每个这样的p结点;
(3) q^.next指向p。
算法:
proc ds0207(var h:pointer; mink,maxk:integer);
{ h:带头结点的单链表的头指针,}
[ if pa^.data<=pb^.data
then [s:=pa; pa:=pa^.next ]
else [s:=pb; pb:=pb^.next ];
s^.next:=hc^.next; hc^.next:=s
]
while pa<>nil do
[ s:=pa; pa:=pa^.next ;
s^.next:=hc^.next; hc^.next:=s
{ 删除所有的其值>mink并且<maxk的结点p}
q.next:=p
endp; {ds0207}
2.8
已知线性表中的元素按值递增排列, 并以单链表作存储结构. 写一高效算法, 删除表中的多余元素, 使得运算后的线性表中所有元素的值均不相同。
设计思想:
从第一个结点开始, 每一结点的值与后一结点的值作比较 , 若相等, 则删除后一结点, 直至整个链
p:=ha; {p:指向头结点}
len:=0;
while (p^.next<>nil) do [ p:=p^.next; len:=len+1]
{当p不空x时, 访问其结点, 并计数}
return(len);
{len:即为此链表的长度)
end; {ds0205_2}
2.6
已知ha和hb分别指向两个单链表的头结点, 且头结点的数据域(整型)中存放链表的长度, 写一算法将这
else [ q:=p; p:=p^.next ]; {p后移}
endp; {ds0208}
2.9
以一维数组和链表作存储结构, 实现线性表就地逆置的算法, 即将线性表
(a1,a2,...an)==>(an,...,a2,a1)
一. 以一维数组为存储结构:
设计思想:
用a[1]与a[n]交换,a[2]与a[n-1]交换,……,以此类推,直至n div 2止。
(2) 若某一链表空, 将另一链表剩余部分依次插入在C表的表首。
算法:
proc ds02011(var hc:pointer; ha,hb:pointer);
{ ha,hb,hc分别为A链.B链和C链的头指针}
pa:=ha; pb:=hb;
new(hc); {生成新链表的头结点}
while (pa<>nil) and (pb<>nil) do {A,B表不空}
算法:
proc ds0201(var a:array[1..size] of integer; var elenum:integer; x:integer);
if elenum=size then error('array overflow')
else [ i:=elenum;
while (i>=1) cand (x<a[i]) do
q:=h; p:=h^.next;
while (p<>nil) and (p^.data<=mink) do
[ q:=p; p:=p^.next ];
{p:其值>mink的结点, q是p的前趋}
while (p<>nil) and (p^.data<maxk) do
[ u:=p; p:=p^.next; dispose(p) ];
注意:应保留p的前趋
算法:
proc ds02012(var ha:pointer; hb,hc:pointer);
{ ha,hb,hc分别为A链.B链和C链的头指针}
pre:=ha; pa:=ha^.next; {pre:pa的前趋}
pb:=hb^.next;
pc:=hc^.next; {pb,pc:总指向hb,hc链的最后一个已考查的结点}
THEN [vc.elem[k+1]:=va.elem[i];k:=k+1;i:=i+1]
ELSE [vc.elem[k+1]:=vb.elem[j];k:=k+1;j:=j+1];
WHILE i<=va.last DO {插入VA的剩余段}
[vc.elem[k+1]:=va.elem[i];k:=k+1;i:=i+1];
2.1
设线性表存于a[1..arrsize]的前elenum个分量中, 且递增有序. 试写一算法,将x插入到线性表的适当位置, 以保持线性表的有序性。
设计思想:
(1) 先查找 x 的插入位置 i ;
(2) 将线性表中自A[i]至A[elenum]的元素后移一个位置;
(3) 最后将x查入到A[i]中, 并且将表长加1。
WHILE j<=vb.last DO {插入VB的剩余段}
[vc.elem[k+1]:=vb.elem[j];k:=k+1;j:=j+1];
vc.last:=k {K为VC中元素个数}
ENDP;{ds0203}
2.5
写出在带头结点的动态单链表结构上实现线性表操作
一. LOCATE(L,X)
二. LENGTH(L)