数据结构实用第二版答案徐孝凯课案.docx

上传人:b****8 文档编号:28298596 上传时间:2023-07-10 格式:DOCX 页数:115 大小:50.62KB
下载 相关 举报
数据结构实用第二版答案徐孝凯课案.docx_第1页
第1页 / 共115页
数据结构实用第二版答案徐孝凯课案.docx_第2页
第2页 / 共115页
数据结构实用第二版答案徐孝凯课案.docx_第3页
第3页 / 共115页
数据结构实用第二版答案徐孝凯课案.docx_第4页
第4页 / 共115页
数据结构实用第二版答案徐孝凯课案.docx_第5页
第5页 / 共115页
点击查看更多>>
下载资源
资源描述

数据结构实用第二版答案徐孝凯课案.docx

《数据结构实用第二版答案徐孝凯课案.docx》由会员分享,可在线阅读,更多相关《数据结构实用第二版答案徐孝凯课案.docx(115页珍藏版)》请在冰豆网上搜索。

数据结构实用第二版答案徐孝凯课案.docx

数据结构实用第二版答案徐孝凯课案

第一章绪习题一

1.有下列几种用二元组表示的数据结构,试画出它们分别对应的图形表示(当出现多个关系时,

对每个关系画出相应的结构图),并指出它们分别属于何种结构。

⑴A=(K,R)其中

K={a1,a2,a3...,an}

R={}

⑵B=(K,R)其中

K={a,b,c,d,e,f,g,h}

R={r}

r={,,,,,,}

⑶C=(K,R)其中

K={a,b,c,d,f,g,h}

R={r}

r={,,,,,,}

⑷D=(K,R)其中

K={1,2,3,4,5,6}

R={r}

r={(1,2),(2,3),(2,4),(3,4),(3,5),(3,6),(4,5),(4,6)}

⑸E=(K,R)其中

K={48,25,64,57,82,36,75,43}

R={r1,r2,r3}

r1={<48,25>,<25,64>,<64,57>,<57,82>,<82,36>,<36,75>,<75,43>}

r2={<48,25>,<48,64>,<64,57>,<64,82>,<25,36>,<82,75>,<36,43>}

r3={<25,36>,<36,43>,<43,48>,<48,57>,<57,64>,<64,75>,<75,82>}

解:

⑴是集合结构;⑵是线性结构;⑶⑷是树型结构;⑸散列结构。

只作为参考。

2.设计二次多项式ax2+bx+c的一种抽象数据类型,假定起名为QIAdratic,

该类型的数据部分分为三个系数项a、b和c,操作部分为:

(请写出下面每一个

操作的具体实现)。

⑴初始化数据成员ab和c(假定用记录类型Quadratie定义成员),每个数据成

员的默认值为0。

QuadraticInitQuadratic(floataa=0,floatbb=0,floatcc=0);

解:

QuadraticInitQuadratic(floataa,floatbb,floatcc)

{

Quadraticq;

q.a=aa;

q.b=bb;

q.c=cc;

returnq;

}

⑵做两个多项式加法,即使对应的系数相加,并返回相加的结果。

QuadraticAdd(Quadraticq1,Quadraticq2);

解:

QuadraticAdd(Quadraticq1,Quadraticq2);

{

Quadraticq;

q.a=q1.a+q2.a;

q.b=q1.b+q2.b;

q.c=q1.c+q2.c;

returnq;

}

⑶根据给定x的值计算多项式的值。

floatEval(Quadraticq,floatx);

解:

floatEval(Quadraticq,floatx)

{

return(q.a*x*x+q.b*x+q.c);

}

⑷计算方程ax2+bx+c=0的两个实数根,对于有实根、无实根和不是实根方程

(即a==0)这三种情况要返回不同的整数值,以便于工作调用函数做不同的处理。

intRoot(Quadraticq,float&r1,float&r2);

解:

intRoot(Quadraticq,float&r1,float&r2)

{

if(q.a==0)return-1;

floatx=q.b*q.b-4*q.a*q.c;

if(x>=0){

r1=(float)(-q.b+sqrt(x))/(2*q.a);

r2=(float)(-q.b-sqrt(x))/(2*q.a);

return1;

}

else

return0;

}

⑸按照ax**2+bx+c的格式(x2用x**2表示)输出二次多项式,在输出时要注意

去掉系数为0的项,并且当b和c的值为负时,其前不能出现加号。

voidPrint(Quadraticq)

解:

voidPrint(Quadraticq)

{

if(q.a)cout<

if(q.b)

if(q.b>0)

cout<<"+"<

else

cout<

if(q.c)

if(q.c>0)

cout<<"+"<

else

cout<

cout<

}

3.用c++函数描述下列每一个算法,并分别求出它们的时间复杂度。

⑴比较同一简单类型的两个数据x1和x2的大小,对于x1>x2,x1=x2和x1

情况分别返回'>''='和'<'字符。

假定简单类型用SimpleType表示,它可通过typedef

语句定义为任一简单类型。

解:

charcompare(SimpleTypex1,SimpleTypex2)

{

if(x1>x2)return'>';

elseif(x1==x2)return'=';

elsereturn'<';

}

其时间复杂度为O

(1)

⑵将一个字符串中的所有字符按相反方的次序重新放置。

解:

voidReverse(char*p)

{

intn=strlen(p);

for(inti=0;i

charch;

ch=p[i]

p[i]=p[n-i-1];

p[n-i-1]=ch;

}

}

其时间复杂度为O(n)

⑶求一维double型数组a[n]中的所有元素之乘积。

解:

doubleproduct(doublea[],intn)

{

doublep=1;

for(inti=0;i

p*=a[i];

returnp;

}

其时间复杂度为O(n)

⑷计算Σni=0xi/i+1的值。

解:

doubleAccumulate(doublex,intn)

{

doublep=1,s=1;

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

p*=x;

s+=p/(i+1);

}

returns;

}

其时间复杂度为O(n)

⑸假定一维数组a[n]中的每个元素值均在[0,200]区间内,分别统计出落在[0,20)

[20,50),[50,80),[80,130),[130,200]等各区间的元素个数。

解:

intCount(inta[],intn,intc[5])//用数组c[5]保存统计结果

{

intd[5]={20,50,80,130,201};//用来保存各统计区间的上限

inti,j;

for(i=0;i<5;i++)c[i]=0;//给数组c[5]中的每个元素赋初值0

for(i=0;i

{

if(a[i]<0||a[i]>200)

return0;//返回数值0表示数组中数据有错,统计失败

for(j=0;j<5;j++)//查找a[i]所在区间

if(a[i]

c[j]++;//使统计相应区间的元素增1

}

return1;//返回数值1表示统计成功

}

其时间复杂度为O(n)

⑹从二维整型数组a[m][n]中查找出最大元素所在的行、列下标。

解:

voidfind(inta[M][N],intm,intn,int&Lin,int&Col)

//M和N为全局常量,应满足M>=n和N>=n的条件,Lin和Col为引用

//形参,它是对应实参的别名,其值由实参带回

{

Lin=0;Col=0;

for(inti=0;i

for(intj=0;j

if(a[i][j]>a[Lin][Col]){Lin=i;Col=j;}

}

其时间复杂度为O(m*n)

4.指出下列各算法的功能并求出其时间复杂度。

⑴intprime(intn)

{

inti=2;

intx=(int)sqrt(n);

while(i<=x){

if(n%i==0)break;

i++;

}

if(i>x)

return1;

else

return0;

}

解:

判断n是否是一个素数,若是则返回数值1,否则返回0。

该算法的时间复杂度为

O(n1/2)。

⑵intsum1(intn)

{

intp=1,s=0;

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

p*=i;

s+=p;

}

returns;

}

解:

计算Σi!

(上标为n,下标为i=1)的值,其时间的复杂度为O(n)。

⑶intsum2(intn)

{

ints=0;

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

intp=1;

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

p*=j;

s+=p;

}

returns;

}

解:

计算Σi!

的值,时间复杂度为O(n2)

⑷intfun(intn)

{

inti=1,s=1;

while(s

s+=++i;

returni;

}

解:

求出满足不等式1+2+3...+i≥n的最小i值,其时间复杂度为O(n1/2)。

⑸voidUseFile(ifstream&inp,intc[10])

//假定inp所对应的文件中保存有n个整数

{

for(inti=0;i<10;i++)

c[i]=0;

intx;

while(inp>>x){

i=x%10;

c[i]++;

}

}

解:

利用数组c[10]中的每个元素c[i]对应统计出inp所联系的整数文件中个位值同为i的整数个

数,时间复杂度为O(n)

⑹voidmtable(intn)

{

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

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

cout<

<

(2)<

cout<

}

}

解:

打印出一个具有n行的乘法表,第i行(1≤i≤n)中有n-i+1个乘法项,每个乘法项为i与j(

i≤j≤n)的乘积,时间复杂度为O(n2)。

⑺voidcmatrix(inta[M][N],intd)

//M和N为全局整型常量

{

for(inti=0;i

for(intj=0;j

a[i][j]*=d;

}

解:

使数组a[M][N]中的每一个元素均详细以d的值,时间复杂度为O(M*N)

⑻voidmatrimult(inta[M][N],intb[N][L],intc[M][L])

//

{

inti,j,k;

for(i=0;i

for(j=0;j

c[i][j]=0;

for(i=0;i

for(j=0;j

for(k=0;k

c[i][j]+=a[i][k]*b[k][j];

}

解:

矩阵相乘,即a[M][N]×b[N][L]→c[M][L],时间复杂度为O(M×N×L)。

5.题目略

⑴解:

voidInitSet(Set&s)

{

for(inti=1;i<=SETSIZE;i++)

s.m[i]=0;

}

⑵解:

voidInitSet(Set&s,inta[],intn)

{

fot(inti=0;i

s.m[a[i]]=1;

}

⑶解:

Setoperator+(Sets1,Sets2)

{

Sets;

InitSet(s);

for(inti=1;i<=SETSIZE;i++)

if((s1.m[i]==1)||s2.m[i]===1))

s.m[i]=1;

returns;

}

⑷解:

Setoperator*(Sets1,Sets2)

{

Sets;

InitSet(s);

for(inti=1;i<=SETSIZE;i++)

if((s1.m[i]==1)&&(s2.m[i]==1))

s.m[i]=1;

returns;

⑸解:

Booleanoperator^(intelt,Sets)

{

if(s.m[elt]==1)

returnTrue;

else

returnFalse;

}

⑹解:

voidInisert(Set&s,intn)

{

s.m[n]=1;

}

⑺解:

voidDelete(Set&s,intn)

{

s.m[n]=0;

}

⑻解:

ostream&operator<<(ostream&ostr,Set&s)

{

ostr<<'{'

for(inti=1;i<=SETSIZE;i++)

if(s.m[i]==1)

ostr<

ostr<<'}'<

returnostr;

}

 

第二章线性表习题二

1.

⑴解:

(79,62,34,57,26,48)

⑵解:

(26,34,48,57,62,79)

⑶解:

(48,56,57,62,79,34)

⑷解:

(56,57,79,34)

⑸解:

(26,34,39,48,57,62)

2.

解:

为了排版方便,假定采用以下输出格式表示单链接表的示意图;每个括号内的数据表示一个元

素结点,其中第一个数据为元素值,第二个数据为后继结点的指针,第一个元素结点前的数值为

表头指针。

⒈(7(79,6),(62,5),(34,4),(57,3),(26,2),(48,0))

⒉(3(26,5),(34,2),(48,4),(57,6),(62,7),(79,0))

⒊(2(48,8),(56,4),(57,6),(62,7),(79,5),(34,0))

⒋(8(56,4),(57,7),(79,5),(34,0))

3.对于List类型的线性表,编写出下列每个算法。

⑴从线性表中删除具有最小值的元素并由函数返回,空出的位置由最后一个元素填补,若

线性表为空则显示出错信息并退出运行。

解:

ElemTypeDMValue(List&L)

//从线性表中删除具有最小值的元素并由函数返回,空出的位置

//由最后一个元素填补,若线性表为空则显示出错信息并退出运行

{

if(ListEmpty(L)){

cerr<<"ListisEmpty!

"<

exit

(1);

}

ElemTypex;

x=L.list[0];

intk=0;

for(inti=1;i

ElemTypey=L.list[i];

if(y

}

L.list[k]=L.list[L.size-1];

L.size--;

returnx;

}

⑵从线性表中删除第i个元素并由函数返回。

解:

intDeletel(List&L,inti)

//从线性表中删除第i个元素并由函数返回

{

if(i<1||i>L.size){

cerr<<"Indexisoutrange!

"<

exit

(1);

}

ElemTypex;

x=L.list[i-1];

for(intj=i-1;j

L.list[j]=L.list[j+1];

L.size--;

returnx;

}

⑶向线性表中第i个元素位置插入一个元素。

解:

voidInser1(List&L,inti,ElemTypex)

//向线性表中第i个元素位置插入一个元素

{

if(i<1||i>L.size+1){

cerr<<"Indexisoutrange!

"<

exit

(1);

}

if(L.size==MaxSize)

{

cerr<<"Listoverflow!

"<

exit

(1);

}

for(intj=L.size-1;j>i-1;j--)

L.list[j+1]=L.list[j];

L.list[i-1]=x;

L.size++;

}

⑷从线性表中删除具有给定值x的所有元素。

解:

voidDelete2(List&L,ElemTypex)

//从线性表中删除具有给定值x的所有元素

{

inti=0;

while(i

if(L.list[i]==x){

for(intj=i+1;j

L.list[j-1]=L.list[j];

L.size--;

}

else

i++;

}

⑸从线性表中删除其值在给定值s和t之间(要求s小于t)的所有元素。

解:

voidDelete3(List&L,ElemTypes,ElemTypet)

//从线性表中删除其值在给定值s和t之间的所有元素

{

inti=0;

while(i

if((L.list[i]>=s)&&(L.list[i]<=t)){

for(intj=i+1;j

L.list[j-i]=L.list[j];

L.size--;

}

else

i++;

}

⑹从有序表中删除其值在给定值s和t之间(要求s小于t)的所有元素。

解:

voidDelete4(List&L,ElemTypes,ElemTypet)

//从有序表中删除其值在给定值s和t之间的所有元素

{

inti=0;

while(i

if(L.list[i]

elsebreak;

if(i

While((i+j

j++;//求出s和t之间元素的个数

for(intk=i+j;k

L.list[k-j]=L.list[k];

L.size-=j;

}

}

⑺将两个有序表合并成一个新的有序表并由变量返回。

解:

voidMerge(List&L1,List&L2,List&L3)

//将两个有序表合并成一个新的有序表并由变量返回

{

if(L1.size+L2.size>MaxSize){

cerr<<"Listoverflow!

"<

exit

(1);

}

inti=0,j=0,k=0;

while((i

if(L1.list[i]<=L2.list[j])

{//将L1中的元素赋给L

L.list[k]=L1.list[i];

i++;

}

else{//将L2中的元素赋给L

L.list[k]=L2.list[j];

j++;

}

k++;

}

while(i

L.list[k]=L1.list[i];

i++;k++;

}

while(j

L.list[k]=L2.list[j];

j++;k++;

}

L.size=k;

}

⑻从线性表中删除所有其值重复的元素,使其所有元素的值均不同,如对于线性表(2,8,9,

2,5,5,6,8,7,2),则执行此算法后变为(2,8,9,5,6,7)。

解:

voidDelete5(List&L)

//从线性表中删除所有其值重复的元素,使其所有元素的值均不同

{

inti=0;

while(i

intj=i+1;

while(j

{//删除重复值为L.list[i]的所有元素

if(L.list[j]==L.list[i]){

for(intk=j+1;k

L.list[k-1]=L.list[k];

L.size--;

}

else

j++;

}

i++;

}

}

4.对于结点类型为LNode的单链接表,编写出下列每个算法。

⑴将一个单链接表按逆序链接,即若原单链表中存储元素的次序为a1,a2,...,an,则

逆序链接后变为an,an-1,...a1。

解:

voidContrary(LNode*&HL)

//将一个单多办实事有按逆序链接

{

LNode*p=HL;//p指向待逆序的第一个结点,初始指向原表头结点

HL=NULL;//HL仍为逆序后的表头指针,禄始值为空

while(p!

=NULL)

{//把原单链表中的结点依次进行逆序链接

LNode*q=p;//q指向待处理的结点

p=p->next;//p指向下一个待逆序的结点

//将q结点插入到已陈序单链表的表头

q->next=HL;

HL=q;

}

}

⑵删除单链表中的第i个结点。

解:

voidDelete1(LNode*&HL,inti)

//删除单链表中的第i个结点

{

if(i<1||HL==NULL){

cerr<<"Indexisoutrange!

"<

exit

(1);

}

LNode*ap,*cp;

ap=NULL;cp=HL;//cp指向当前结点,ap指向其前驱结点

intj=1;

while(cp!

=NULL)

if(j==i)

break;//cp结点即为第i个结点

else{//继续向后寻找

ap=cp;

cp=cp->next;

j++;

}

if(cp==NULL){

cerr<<"Indexisoutrange!

"<

exit

(1);

}

if(ap==NULL)

HL=HL->next;

else

ap->next=cp->next;

deletecp;

}

⑶从单链表中查找出所有元素的最大值,该值由函数返回,若单链表为空,则显示出错信息

并停止运行。

解:

ElemTypeMaxValue(LNode*HL)

//从单链表中查找出所有元素的最大值,该值由函数返回

{

if(HL==NULL){

cerr<<"Linkedlistisempty!

"<

exit

(1);

}

ElemTypemax=HL->data;

LNode*p=HL->next;

while(p!

=NULL){

if(maxdata)max=p->data;

p=p->next;

}

returnmax;

}

⑷统计出单链表中结点的值等于给定值x的结点数。

解:

intCount(LNode*HL,ElemTypex)

//统计出单链表中结点的值等于给定值x的结点数

{

intn=0;

while(HL!

=NULL){

if(HL->data==x)n++;

HL=HL->next;

}

returnn;

}

⑸根据一

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1