严蔚敏版数据结构课后习题答案_第1页
严蔚敏版数据结构课后习题答案_第2页
严蔚敏版数据结构课后习题答案_第3页
严蔚敏版数据结构课后习题答案_第4页
严蔚敏版数据结构课后习题答案_第5页
已阅读5页,还剩222页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第1章绪论

1.1简述下列术语:数据,数据元素、数据对象、数据结构、存储结

构、数据类型和抽象数据类型。

解:数据是对客观事物的符号表示。在计算机科学中是指所有能输入

到计算机中并被计算机程序处理的符号的总称。

数据元素是数据的基本单位,在计算机程序中通常作为一个整体

进行考虑和处理。

数据对象是性质相同的数据元素的集合,是数据的一个子集。

数据结构是相互之间存在一种或多种特定关系的数据元素的

集合。

存储结构是数据结构在计算机中的表示。

数据类型是一个值的集合和定义在这个值集上的一组操作的总

称。

抽象数据类型是指一个数学模型以及定义在该模型上的一组操

作。是对一般数据类型的扩展。

1.2试描述数据结构和抽象数据类型的概念与程序设计语言中数据

类型概念的区别。

解:抽象数据类型包含一般数据类型的概念,但含义比一般数据

类型更广、更抽象。一般数据类型由具体语言系统内部定义,直接提

供给编程者定义用户数据,因此称它们为预定义数据类型。抽象数据

类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所

进行的操作。在定义抽象数据类型中的数据部分和操作部分时,要求

只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作

的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接

口。

1.3设有数据结构(D,R),其中

{dl/2/3,d4},R={r},{(d1/2),(d2,d3),(d3,d4)}

试按图论中图的画法惯例画出其逻辑结构图。

1.4试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有

理数的定义(有理数是其分子、分母均为自然数且分母不为零的分

数)。

解:

ADTComplex{

0数据对象:D={r,i|r,i为实数}

数据关系:R={〈r,i>}

基本操作:

。oInitComplex(&C,re,im)

操作结果:构造一个复数C,其实部和虚部分别为re

和im

DestroyCmop1ex(&C)

操作结果:销毁复数C

。Get(C,k,&e)

。。。操作结果:用e返回复数C的第k元的值

。。Put(&C,k,e)

。操作结果:改变复数C的第k元的值为e

IsAscending(C)

…o操作结果:如果复数C的两个元素按升序排列,则返回1,

否则返回0

。oIsDescending(C)

。o操作结果:如果复数C的两个元素按降序排列,则返回1,

否则返回0

。Max(C,&e)

。。。操作结果:用e返回复数C的两个元素中值较大的一个

。oMin(C,&e)

。。操作结果:用e返回复数C的两个元素中值较小的一个

}ADTComp1ex

ADTRationalNumber{

。数据对象:D={s,m|s,m为自然数,且m不为0}

数据关系:R={〈s,m>}

0基本操作:

eInitRationalNumber(&R,s,m)

操作结果:构造一个有理数R,其分子和分母分别为s

和m

oDestroyRationa1Number(&R)

操作结果:销毁有理数R

。。。Get(R,k,&e)

。。。操作结果:用e返回有理数R的第k元的值

3Put(&R,k,e)

。。操作结果:改变有理数R的第k元的值为e

。oIsAscending(R)

。。。操作结果:若有理数R的两个元素按升序排列,则返回1,

否则返回0

。IsDescending(R)

。操作结果:若有理数R的两个元素按降序排列,则返回1,否

则返回0

。。。Max(R,&e)

。操作结果:用e返回有理数R的两个元素中值较大的一个

Min(R,&e)

。。操作结果:用e返回有理数R的两个元素中值较小的一个

}ADTRationaINumber

1.5试画出与下列程序段等价的框图。

(1)product=1;i=1;

while(i<=n){

product*=i;

i++;

}

⑵i=0;

dO(

i++;

}while((i!=n)&&(a[i]!=x));

(3)switch{

casex<y:z=y­x;break;

casex=y:z=abs(x*y);break;

defauIt:z=(x—y)/abs(x)*abs(y);

)

1.6在程序设计中,常用下列三种不同的出错处理方式:

(1)用exit语句终止执行并报告错误;

(2)以函数的返回值区别正确返回或错误返回;

(3)设置一个整型变量的函数参数以区别正确返回或某种错误

返回。

试讨论这三种方法各自的优缺点。

解:(l)exit常用于异常错误处理,它可以强行中断程序的执行,

返回操作系统。

(2)以函数的返回值判断正确与否常用于子程序的测试,便于实

现程序的局部控制。

(3)用整型函数进行错误处理的优点是可以给出错误类型,便于

迅速确定错误。

1.7在程序设计中,可采用下列三种方法实现输出和输入:

(1)通过scanf和printf语句;

(2)通过函数的参数显式传递;

(3)通过全局变量隐式传递。

试讨论这三种方法的优缺点。

解:(1)用seanf和printf直接进行输入输出的好处是形象、

直观,但缺点是需要对其进行格式控制,较为烦琐,如果出现错误,则

会引起整个系统的崩溃。

(2)通过函数的参数传递进行输入输出,便于实现信息的隐

蔽,减少出错的可能。

(3)通过全局变量的隐式传递进行输入输出最为方便,只需修改

变量的值即可,但过多的全局变量使程序的维护较为困难。

1.8设n为正整数。试确定下列各程序段中前置以记号@的语句的频

度:

(1)i=1;k=0;

while(i<=n-l){

@k+=10*i;

i++;

)

(2)i=l;k=0;

do{

@k+=10*i;

i++;

}while(i<=n-1);

⑶i=l;k=0;

while(i<=n-l){Ai++;

@k+=10*i;

)

(4)k=0;

for(i=l;i<=n;i++){

for(j=i;j<=n;j++)

@k++;

)

(5)for(i=1;i<=n;i++){

for(j=1;j<=i;j++){

for(k=l;k<=j;k++)

@x+=delta;

}

(6)i=1;j=0;

whi1e(i+j<=n){A©if(i>j)

j++;

elsei++;

)

⑺x=n;y=0;〃!)是不小于1的常数

while(x>=(y+1)*(y+l)){

@y++;

)

(8)x=91;y=l00;

while(y>0){

@if(x>100){x-=10;y―;}

elsex++;

)

解:(1)n-1

(2)n-1

(3)n—1

(4)/(自)+62)+…+1二噂

(5)1+(1+2)+(l+2+3)+一.+(1+2+3+...+n)=£W

z=i2

二空小D=扛(八

乙M乙M乙i-l乙i»l

=*n(n+1)(2〃+1)+;n(n+1)=n(n+1)(2〃+3)

(6)n

(7)[册」向下取整

(8)1100

1.9假设n为2的乘幕,并且n>2,试求下列算法的时间复杂度及

变量count的值(以n的函数形式表示)o

intTime(intn){

count=0;,x=2;

while(x<n/2){

。ox*=2;scount++;

。)

returncount;

,}

解:6>(10g2H)

count=log2n-2

1.11已知有实现同一功能的两个算法,其时间复杂度分别为。(2〃)和

。(,严),假设现实计算机可连续运算的时间为o秒(100多天),又每

秒可执行基本操作(根据这些操作来估算算法时间复杂度)105次。试

问在此条件下,这两个算法可解问题的规模(即n值的范围)各为多

少?哪个算法更适宜?请说明理由。

解:2"=10%。n=40

/710=io,2on=16

则对于同样的循环次数n,在这个规模下,第二种算法所花费的

代价要大得多。故在这个规模下,第一种算法更适宜。

1.12设有以下三个函数:

/(«)=21n4+n2+1003,g(〃)=15/+500〃3,A(n)=500n35+wlogw

请判断以下断言正确与否:

(1)f(n)是。(g(n))

(2)h(n)是0(f(n))

(3)g(n)是0(h(n))

(4)h(n)是0(n*

(5)h(n)是O(nlogn)

解:⑴对⑵错(3)错(4)对⑸错

1.13试设定若干n值,比较两函数/和50〃log2力的增长趋势,并确定

n在什么范围内,函数小的值大于50〃log2〃的值。

解:小的增长趋势快。但在“较小的时候,50〃log2〃的值较大。

2

。当n>438时,n>50wlog2n

1.14判断下列各对函数/(〃)和g(〃),当〃―8时,哪个函数增长更

快?

(1)/(〃)=10/22+In(〃!+10〃),g(n)=2n4+n+7

(2)/(n)=(ln(w!)+5)2,g(n)=13n25

(3)f(n)=n2'+y/n4+1,g(〃)=(ln(n!))2+n

(4)/(n)=2〃)+(2〃J,,g®=〃0+/

解:(1)g(n)快(2)g(n)快(3)f(n)快(4)f(n)快

L15试用数学归纳法证明:

(1)=〃(〃+1)(2〃+1)/6(/?>0)

i=l

(2)=(xM+,-l)/(x-l)®§(x^l,n>0)

i=0

(3)£2-1=2"-1。(n>l)

i=l

(4)£(2i-l)="

5之1)

t=l

1.16试写一算法,自大至小依次输出顺序读入的三个整数X,Y和Z

的值

解:

intmax3(intx,inty,intz)

(

if(x>y)

if(x>z)returnx;

。oelsereturnz;

else

if(y>z)returny;

e1sereturnz;

}

1.17已知k阶斐波那契序列的定义为

d

0°Z)=。,/=o,・・・,A.2=o,fk_}=i;

d+

fn=fn-\fn-2+***+fn-k9〃=%,%+『••

试编写求k阶斐波那契序列的第m项值的函数算法,k和m均以

值调用的形式在函数参数表中出现。

解:k>0为阶数,n为数列的第n项

intFibonacci(intk,intn)

if(k<l)exit(OVERFLOW);

int*p,x;

p=newint[k+1];

。if(!p)exit(OVERFLOW);

。inti,j;

。for(i=0;iVk+1;i++){

。oif(i<k-l)p[i]=0;

。。ee1sep[i]=1;

)

。。for(i=k+1;i<n+l;i++){

。x=p[0];

s。°for(j=0;j<k;j++)p[j]=pLj+1];

。。op[k]=2*p[k-l]-x;

0}

。。returnp[k];

)

1.18假设有A,B,C,D,E五个高等院校进行田径对抗赛,各院校

的单项成绩均已存入计算机,并构成一张表,表中每一行的形式为

项目名性别校名成绩得分

编写算法,处理上述表格,以统计各院校的男、女总分和团体总分,并

输出。

解:

typedefenum{A,B,C,D,E}SchooIName;

typedefenum{Female,Male}SexType;

typedefstruct{

ocharevent[3];//项目

SexTypesex;

oSchoolNameschoo1;

ointscore;

}Component;

typedefstruct{

intMaleSum;〃男团总分

ointFema1eSum;//女团总分

intTotaiSum;//团体总分

}Sum;

SumSumScore(SchoolNamesn,Componenta口,intn)

(

oSumtemp;

temp.MaleSum=0;

etemp.FemaleSum=0;

temp.TotalSunFO;

inti;

for(i=0;i<n;i++){

…if(a[i].schoo1=sn){

oif(a[i].sex=二Ma1e)temp.MaleSum+=a[i].sc

ore;

3。if(a[i].sex二二Female)temp.FemaleSum+=

a[i].score;

6)

0}

otemp.TotalSum=temp.MaleSum+temp.FemaleSum;

returnternp;

)

1.19试编写算法,计算。2的值并存入数组a[0..arrsize-1]

的第i-1个分量中(i=l,2,n)o假设计算机中允许的整数最大

值为maxint,则当n>arrsize或对某个攵(14女。),使

人〉maxint时,应按出错处理。注意选择你认为较好的出错处理方

法。

解:

#include<iostream.h>

#include<stdlib.h>

#defineMAXINT65535

#defineArrSize100

intfun(inti);

intmain()

inti,k;

inta[ArrSize];

ocout«'Enterk:〃;

cin»k;

oif(k>ArrSize-1)exit(0);

ofor(i=0;i<=k;i++){

oif(i==0)a[i]=l;

3else{

。if(2*i*a[i-1]>MAXINT)exit(0);

o3seIsea[i]=2*i[i-1];

6)

°}

for(i=0;i<=k;i++){

sif(a[i]>MAXINT)exit(0);

oelsecout<Va[i"<"〃;

o}

ereturn0;

)

1.20试编写算法求一元多项式的值以+为3的值匕(%),并确定算

x=0

法中每一语句的执行次数和整个算法的时间复杂度。注意选择你认为

较好的输入和输出方法。本题的输入为q(i=0』,…,〃),/和〃,输出为

匕(%)°

解:

#include<iostream,h>

#inc1ude<stdlib.h>

#defineN10

doublepo1ynomai1(inta[],inti,doublex,intn);

intmain()

(

doublex;

intn,i;

inta[N];

。cout<<〃输入变量的值X:〃;

。cin>>x;

cout<<〃输入多项式的阶次n:";

cin>>n;

oif(n>N-l)exit(0);

cout<V”输入多项式的系数a[0]--a[n]

。for(i=0;i<=n;i++)cin>>a[i];

。cout<</zThepolynomailvalueis〃V〈polynoma

i1(a,n,x,n)«end1;

。return0;

}

doublepolynomail(inta[],inti,doublex,i

ntn)

oif(i>0)returna[n-i]+polynomai1(a,i-l,x,n)*x;

oe1sereturna[n];

}

本算法的时间复杂度为。(n)。

第2章线性表

2.1描述以下三个概念的区别:头指针,头结点,首元结点(第一个元

素结点)。

解:头指针是指向链表中第一个结点的指针。首元结点是指链表

中存储第一个数据元素的结点。头结点是在首元结点之前附设的一个

结点,该结点不存储数据元素,其指针域指向首元结点,其作用主要是

为了方便对链表的操作。它可以对空表、非空表以及首元结点的操作

进行统一处理。

2.2填空题。

解:(1)在顺序表中插入或删除一个元素,需要平均移动表中一

差元素,具体移动的元素个数与元素在表也物位置有关。

(2)顺序表中逻辑上相邻的元素的物理位置装紧邻。单链

表中逻辑上相邻的元素的物理位置丕二定紧邻。

(3)在单链表中,除了首元结点外,任一结点的存储位置由晶肱

驱结点的链域的值埼示。

(4)在单链表中设置头结点的作用是癌人初瞬聋元缙点时

不用进行特殊处理。

2.3在什么情况下用顺序表比链表好?

解:当线性表的数据元素在物理位置上是连续存储的时候,用顺

序表比用链表好,其特点是可以进行随机存取。

2.4对以下单链表分别执行下列各程序段,并画出结果示意图。

ITTT

PQRS

解:

⑶L―►2——*51

1T

PQ

⑸L―►2——*5——»1——►3——»5

nrTTT

PQRS

(6)L―►2——►10——►14------►6——»16

TTT

PQRS

(7)L—►2------►10------»14-----►6-----»16—►-

vvv

PQRS

2.5画出执行下列各行语句后各指针及链表的示意图。

L=(LinkList)malloc(sizeof(LNode));P=L;

for(i=1;i<=4;i++){

,,P->next=(LinkList)mal1oc(sizeof(LNode));

,P=P->next;P->data=i*2—1;

,}

,P->next=NULL;

,for(i=4;i>=l;i—)Ins_LinkList(L,i+1,i*2);

ofor(i=l;i<=3;i++)Del_LinkList(L,i);

解:

L-►

P

L•,1,3•5,7A

]

p

-fl---►2->3||->4J_►578A

1

P

L―►―»2——»4——►6——►7——»8A

T

p

2.6已知L是无表头结点的单链表,且P结点既不是首元结点,也不

是尾元结点,试从下列提供的答案中选择合适的语句序列。

a.在P结点后插入S结点的语句序列是

b.在P结点前插入S结点的语句序列是

C.在表首插入S结点的语句序列是

d.在表尾插入S结点的语句序列是

(1)P—>next=S;

(2)P->next=P—>next->next;

(3)P->next=S->next;

(4)S->next=P->next;

(5)S—>next=L;

(6)S->next=NULL;

(7)Q=P;

(8)while(P->next!=Q)P=P—>next;

(9)while(P—>next!=NULL)P=P->next;

(10)P=Q;

(11)P=L;

(12)L=S;

(13)L=P;

解:a.(4)(1)

ob.(7)(11)(8)(4)(1)

oc.(5)(12)

。。d.(9)(1)(6)

2.7已知L是带表头结点的非空单链表,且P结点既不是首元结点,

也不是尾元结点,试从下列提供的答案中选择合适的语句序列。

a.删除P结点的直接后继结点的语句序列是

b.删除P结点的直接前驱结点的语句序列是

c.删除P结点的语句序列是

d.删除首元结点的语句序列是

O

e.删除尾元结点的语句序列是____________________________

(1)P=P—>next;

(2)P—>next=P;

(3)P->next=P—>next->next;

(4)P=P->next->next;

(5)while(P!=NULL)P=P->next;

(6)whi1e(Q->next!=NULL){P=Q;Q=Q->next;

(7)while(P->next!=Q)P=P—>next;

(8)whi1e(P->next—>next!=Q)P=P->next;

(9)while(P->next->next!=NULL)P=P->next;

(10)Q=P;

(11)Q=P->next;

(12)P=L;

(13)L=L->next;

(14)free(Q);

解:a.(11)(3)(14)

b.(10)(12)(8)⑶(14)

…c.(10)(12)(7)(3)(14)

。。d.(12)(11)(3)(14)

…e.(9)(11)(3)(14)

2.8已知P结点是某双向链表的中间结点,试从下列提供的答案中

选择合适的语句序列。

a.在P结点后插入S结点的语句序列是

b.在P结点前插入S结点的语句序列是

c.删除P结点的直接后继结点的语句序列是

d.删除P结点的直接前驱结点的语句序列是

e.删除P结点的语句序列是______________________________

(1)P->next=P->next->next;

(2)P->priou=P->priou->priou;

(3)P->next=S;

(4)P->priou=S;

⑸S->next=P;

(6)S->priou=P;

(7)S->next=P->next;

(8)S—>priou=P->priou;

(9)P->priou->next=P->next;

(10)P->priou->next=P;

(11)P->next—>priou=P;

(12)P->next->priou=S;

(13)P->priou->next=S;

(14)P->next->priou=P->priou;

(15)Q=P->next;

(16)Q=P->priou;

(17)free(P);

(18)free(Q);

解:a.(7)(3)(6)(12)

。b.(8)(4)(5)(13)

。c.(15)(1)(11)(18)

d.(16)(2)(10)(18)

…e.(14)(9)(17)

2.9简述以下算法的功能。

(1)StatusA(LinkedListL){〃L是无表头结点的单

链表

if(L&&L->next){

。Q=L;L=L->next;。P=L;

,«>while(P—>next)P=P—>next;

。。P->next=Q;,Q->next=NULL;

d)

,returnOK;

。}

(2)voidBB(LNode*s,LNode*q){

…p=s;

。,while(p->next!=q)p=p->next;

。p->next=s;

oft)

voidAA(LNode*pa,LNode*pb){

。〃pa和pb分别指向单循环链表中的两个结点

,BB(pa,pb);

ddBB(pb,pa);

6)

解:(1)如果L的长度不小于2,将L的首元结点变成尾元

结点。

(2)将单循环链表拆成两个单循环链表。

2.10指出以下算法中的错误和低效之处,并将它改写为一个既正确

又高效的算法。

StatusDeleteK(SqList&a,inti,intk)

〃本过程从顺序存储结构的线性表a中删除第i个元素起的k

个元素

。if(i<1||k<0I|i+k>a.1ength)returnINFEAS

IBLE;〃参数不合法

else(

for(count=l;count<k;count++){

〃删除第一个元素

。for(j=a.1ength;j>=i+l;j—)a.e1em[j-

i]=a.e1em[j];

sa.1ength—;

)

returnOK;

)

解:

StatusDe1eteK(SqList&a,inti,intk)

(

。〃从顺序存储结构的线性表a中删除第i个元素起的k个元素

。〃注意i的编号从0开始

intj;

oif(i<0||i>a.length-11|k<0||k>a.Iength-i)re

turnINFEASIBLE;

for(j=0;j<=k;j++)

o3a.elem[j+i]=a.elem[j+i+k];

a.1ength=a.1ength-k;

returnOK;

}

2.11设顺序表va中的数据元素递增有序。试写一算法,将x插入

到顺序表的适当位置上,以保持该表的有序性。

解:

StatusInsertOrderList(SqList&va,ElemTypex)

{

〃在非递减的顺序表va中插入元素x并使其仍成为顺序表的

算法

ointi;

oif(va.length==va.1istsize)return(0VER

FLOW);

for(i=va.length;i>0,x<va.e;i--)

oova.elem[i]=va.elem[i-l];

ova.elem[i]=x;

va.1ength++;

oreturn0K;

)

2.12设A=(q,…必,)和8=(配…编均为顺序表,A和9分别为A和

8中除去最大共同前缀后的子表。若4=9=空表,则A=5;若A=空

表,而3T空表,或者两者均不为空表,且A的首元小于B,的首元,则

A<8;否则A>8。试写一个比较A,B大小的算法。

解:

StatusCompareOrderList(SqList&A,SqList&B)

(

ointi,k,j;

。k=A.length>B.length?A.Iength:B.length;

for(i=0;i<k;i++){

。if(A.elem[i]>B.e1em[i])j=1;

。if(A.elemLi]<B.elem[i])j=-1;

0}

if(A.1ength>k)j=1;

。if(B.length>k)j=-l;

if(A.length=B.length)j=0;

returnj;

}

2.13试写一算法在带头结点的单链表结构上实现线性表操作Locat

e(L,x);

解:

intLocateElem_L(LinkList&L,ElemTypex)

3inti=0;

LinkListp=L;

owhile(p&&p->data!=x){

o0P=p->next;

oi++;

)

if(!p)return0;

oelsereturni;

}

2.14试写一算法在带头结点的单链表结构上实现线性表操作Lengt

h(L)o

解:

//返回单链表的长度

intListLength—L(LinkList&L)

(

inti=O;

LinkListp=L;

oif(p)p=p—next;

owhile(p){

°p=p->next;

°oi++;

}

returni;

}

2.15已知指针ha和hb分别指向两个单链表的头结点,并且已知两

个链表的长度分别为m和n。试写一算法将这两个链表连接在一起,

假设指针he指向连接后的链表的头结点,并要求算法以尽可能短的

时间完成连接运算。请分析你的算法的时间复杂度。

解:

voidMergeList_L(LinkList&ha,LinkList&hb,LinkL

ist&hc)

{

oLinkListpa,pb;

opa=ha;

pb=hb;

whi1e(pa->next&&pb->next){

pa=pa—>next;

。pb=pb->next;

)

if(!pa->next){

oohc=hb;

owhile(pb—>next)pb=pb—>next;

oopb->next=ha->next;

}

3else{

ehc=ha;

。while(pa->next)pa=pa->next;

opa->next=hb->next;

)

}

2.16已知指针la和lb分别指向两个无头结点单链表中的首元结

点。下列算法是从表la中删除自第i个元素起共len个元素后,将它

们插入到表1b中第i个元素之前。试问此算法是否正确?若有错,请

改正之。

StatusDeleteAndlnsertSub(LinkedListla,Li

nkedList1b,inti,intj,intlen)

(

oif(i<0|Ij<0||1en<0)returnINFEASIBLE;

op=la;k=l;

Jwhile(k<i){p=p—>next;k++;o}

°q=P;

while(k<=len){«>q=q->nextk++;}

s=1b;k=l;

while(k<j){s=s—>next;6k++;。}

os->next=p;sq—>next=s->next;

returnOK;

解:

StatusDeleteAndInsertSub(LinkList&1

a,LinkList&1b,inti,intj,int1en)

(

LinkListp,q,s,prev=NULL;

ointk=l;

oif(i<0||j<0I|len<0)returnINFEASIBLE;

〃在1a表中查找第i个结点

P=la;

while(p&&k<i){

。prev=p;

3op=p->next;

ok++;

)

if(!p)returnINFEASIBLE;

。//在1a表中查找第i+1en-l个结点

。q二P;。k=1;

while(q&&k<len){

ooq二p—>next;

k++;

oif(!q)returnINFEASIBLE;

//完成删除,注意,i=l的情况需要特殊处理

oif(!prev)la=q->next;

e1seprev->next=q->next;

。//将从la中删除的结点插入到lb中

if(j=l){

3oq->next=1b;

。1b=p;

0)

else{

os=lb;。k=l;

owhile(s&&k<j-1){

s=s->next;

3。k++;

oif(!s)returnINFEASIBLE;

3q->next=s->next;

s->next=p;〃完成插入

}

oreturnOK;

}

2.17试写一算法,在无头结点的动态单链表上实现线性表操作Ins

ert(L,i,b),并和在带头结点的动态单链表上实现相同操作的算法

进行比较。

2.18试写一算法,实现线性表操作Deleted,i),并和在带头结点

的动态单链表上实现相同操作的算法进行比较。

2.19已知线性表中的元素以值递增有序排列,并以单链表作存储结

构。试写一高效的算法,删除表中所有值大于mink且小于maxk

的元素(若表中存在这样的元素),同时释放被删结点空间,并分析你

的算法的时间复杂度(注意,mink和maxk是给定的两个参变量,它们

的值可以和表中的元素相同,也可以不同)。

解:

StatusListDelete_L(LinkList&L,ElemTypemin

k,ElemTypemaxk)

(

oLinkListp,q,prev=NULL;

oif(mink>maxk)returnERROR;

P=L;

oprev=p;

op=p->next;

owhile(p&&p->data<maxk){

oif(p->data<=mink){

prev=p;

p=p->next;

03e1se{

…。prev->next=p->next;

ooq=p;

p=p->next;

。free(q);

oo)

6)

oreturnOK;

}

2.20同2.19题条件,试写一高效的算法,删除表中所有值相同的

多余元素(使得操作后的线性表中所有元素的值均不相同),同时释放

被删结点空间,并分析你的算法的时间复杂度。

解:

voidListDelete_LSameNode(LinkList&L)

{

LinkListp,q,prev;

P=L;

prev=p;

op=p->next;

owhile(p){

prev=p;

o6p=p_>next;

…if(p&&p->data==prev->data){

sb。prev->next=p->next;

q=P;

。。p=p->next;

free(q);

2.21试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将

线性表(4,•••,4)逆置为(明,…,q)。

解:

//顺序表的逆置

StatusListOppose_Sq(SqList&L)

(

inti;

ElemTypex;

ofor(i=0;i<L.1ength/2;i++){

。3x=L.elem[i];

。oL.elem[i]=L.elem[L.length—1-i];

oL.elem[L.1ength-1—i]=x;

returnOK;

2.22试写一算法,对单链表实现就地逆置。

解:

//带头结点的单链表的逆置

StatusListOppose_L(LinkList&L)

(

LinkListp,q;

6P=L;

op=p->next;

L->next=NULL;

whi1e(p){

q二P;

op=p->next;

。q->next=L->next;

J3L->next=q;

0)

oreturnOK;

}

2.23设线性表A=(%,生,…4),B=(A也,…也),试写一个按下列规

则合并A,B为线性表C的算法,即使得

6,°C=(q,4,…4,%%,…也》当机工〃时;

,,C=(q,4,…MM,,%,…当〃?>〃时。

线性表A,B和C均以单链表作存储结构,且C表利用A表和B表中的

结点空间构成。注意:单链表的长度值m和n均未显式存储。

解:

//将合并后的结果放在C表中,并删除B表

StatusListMerge_L(LinkList&A,LinkList&B,L

inkList&C)

(

。LinkListpa,pb,qa,qb;

pa=A->next;

。pb=B->next;

C=A;

whi1e(pa&&pb){

3qa=pa;oqb=pb;

。pa=pa->next;pb=pb->next;

oqb->next=qa->next;

°oqa->next=qb;

)

。if(!pa)qb->next=pb;

pb=B;

free(pb);

oreturnOK;

2.24假设有两个按元素值递增有序排列的线性表A和B,均以单链

表作存储结构,请编写算法将A表和B表归并成一个按元素值递减有

序(即非递增有序,允许表中含有值相同的元素)排列的线性表C,

并要求利用原表(即A表和B表)的结点空间构造C表。

解:

//将合并逆置后的结果放在C表中,并删除B表

StatusListMergeOppose_L(LinkList&A,Link

List&B,LinkList&C)

{

oLinkListpa,pb,qa,qb;

opa二A;

opb=B;

6qa=pa;//保存pa的前驱指针

oqb=pb;o//保存pb的前驱指针

pa=pa->next;

opb=pb->next;

oA->next=NULL;

C=A;

owhile(pa&&pb){

oif(pa->data<pb->data){

o。qa=pa;

pa=pa->next;

…qa—>next=A->next;〃将当前最小结点插入A表表头

oA->next=qa;

0}

ooelse(

°qb=pb;

jo。pb=pb—>next;

qb—>next=A->next;〃将当前最小结点插入A表表

。A-〉next=qb;

)

)

owhile(pa){

eqa二pa;

。pa=pa->next;

qa->next=A—>next;

»A->next=qa;

)

while(pb){

oqb=pb;

oopb=pb—>next;

ooqb—>next=A->next;

A->next=qb;

)

opb二B;

free(pb);

returnOK;

}

2.25假设以两个元素依值递增有序排列的线性表A和B分别表示

两个集合(即同一表中的元素值各不相同),现要求另辟空间构成一个

线性表C,其元素为A和B中元素的交集,且表C中的元素有依值递

增有序排列。试对顺序表编写求C的算法。

解:

//将A、B求交后的结果放在C表中

StatusListCross_Sq(SqList&A,SqList&B,SqList&C)

(

ointi=0,j=0,k=0;

while(i<A.length&&j<B.length){

if(A.e1em[i]<B.elem[j])^i++;

else

oo。if(A.e1em[i]>B.elem[j])j++;

oelse{

eListInsert_Sq(C,k,A.e1em[i]);

o。i++;

。。k++;

6}

。}

areturnOK;

}

2.26要求同2.25题。试对单链表编写求C的算法。

解:

//将A、B求交后的结果放在C表中,并删除B表

StatusListCross_L(LinkList&A,LinkList&B,L

inkList&C)

(

oLinkListpa,pb,qa,qb,pt;

pa=A;

opb=B;

qa=pa;//保存pa的前驱指针

qb=pb"//保存pb的前驱指针

pa=pa->next;

opb=pb->next;

C=A;

owhi1e(pa&&pb){

soif(pa->data<pb->data){

pt=pa;

。pa=pa->next;

。qa->next=pa;

3。free(pt);

)

e1se

。。if(pa—>data>pb->data){

e。。pt=pb;

。。opb=pb—>next;

。qb->next=pb;

。。free(pt);

)

。。eIse{

。oqa=pa;

3。pa=pa->next;

}

)

whi1e(pa){

pt=Pa;

pa=pa->next;

oqa->next=pa;

free(pt);

while(pb){

o3pt=pb;

opb=pb->next;

qb—>next=pb;

free(pt);

0}

opb=B;

free(pb);

returnOK;

}

2.27对2.25题的条件作以下两点修改,对顺序表重新编写求

得表C的算法。

(1)假设在同一表(A或B)中可能存在值相同的元素,但要求新

生成的表C中的元素值各不相同;

(2)利用A表空间存放表C。

解:

(1)

//A、B求交,然后删除相同元素,将结果放在C表中

StatusListCrossDelSame_Sq(SqList&A,SqList&B,

SqList&C)

ointi=0,j=0,k=0;

3while(i<A.1ength&&j<B.1ength){

o。if(A.elem[i]<B.elem[j]%i++;

ooe1se

oo。if(A.e1em[i]>B.elem[j])j++;

oooe1se{

jif(C.Iength==0){

3e。Listinsert_Sq(C,k,A.e1em[i]);

。k++;

d0d0}

else

oo。。。if(C.elem[C.1ength-1]!=A.e1e

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论