数据结构实用教程第二版答案徐孝凯.docx
- 文档编号:24956734
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:115
- 大小:46.83KB
数据结构实用教程第二版答案徐孝凯.docx
《数据结构实用教程第二版答案徐孝凯.docx》由会员分享,可在线阅读,更多相关《数据结构实用教程第二版答案徐孝凯.docx(115页珍藏版)》请在冰豆网上搜索。
数据结构实用教程第二版答案徐孝凯
第一章绪习题一
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(max p=p->next; } returnmax; } ⑷统计出单链表中结点的值等于给定值x的结点数。 解: intCount(LNode*HL,ElemTypex) //统计出单链表中结点的值等于给定值x的结点数 { intn=0; while(HL! =NULL){ if(HL->data==x)n++; HL=HL->next; } returnn; } ⑸根据一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实用教程 第二 答案 徐孝凯