数据结构教程Java习题解答.docx
《数据结构教程Java习题解答.docx》由会员分享,可在线阅读,更多相关《数据结构教程Java习题解答.docx(70页珍藏版)》请在冰豆网上搜索。
数据结构教程Java习题解答
第一章绪论
1.1单选题
1.D2.C3.D4.B5.A
6.B7.C8.C9.A10.B
第10小题提示:
在含有n个元素的数据表中顺序查找任一元素的平均比较次数为
,pi为查找第i个元素的概率,ci是查找第i个元素时需要比较的元素数,查找所有元素的概率之和为1,若查找每个元素的概率相同,则平均查找长度的计算公式可简化为
。
此题的计算式为
=35/12
1.2算法分析题
1.判断n是否为一个素数,若是则返回逻辑值true,否则返回逻辑值false。
该算法的时间复杂度为O(
)。
2.计算
的值。
时间复杂度为O(n)。
3.计算
的值。
时间复杂度为O(n2)。
4.求出满足不等式1+2+3+...+i≥n的最小i值。
时间复杂度为O(
)。
提示:
因为1+2+3+...+i=(1+i)i/2,即当n很大时i的平方与n成正比,所以i的值(即函数中while循环的次数)与n的平方根成正比。
5.打印出一个具有n行的乘法表,第i行(1≤i≤n)中有n-i+1个乘法项,每个乘法项为i与j(i≤j≤n)的乘积。
时间复杂度为O(n2)。
6.统计并返回二维数组a中大于等于k的元素的个数。
时间复杂度为O(m×n),假定m和n分别表示二维数组a的行数和列数。
7.矩阵相乘,即a[m][n]×b[n][p]→c[m][p]。
时间复杂度为O(M×N×P)。
这里假定二维数组a的行列数为m和n,二维数组b的行列数为n和p,二维数组c的行列数为m和p。
1.3算法设计题
设计二次多项式ax2+bx+c的一种抽象数据类型,假定起名为Quadratic,该类型的数据部分为双精度类型的3个系数项a、b和c,操作部分为:
(1)初始化二次多项式中的三个数据成员a、b和c。
Quadratic(doubleaa,doublebb,doublecc);
(2)做两个多项式加法,即它们对应的系数相加,返回相加结果。
Quadraticadd(Quadraticq);
(3)根据给定x的值计算多项式的值并返回。
doublevalue(doublex);
(4)计算多项式等于0时的两个实数根,对于有实根、无实根和不是二次方程(即a==0)这3种情况需要返回不同的整数值(1,0,-1),以便调用函数能够做不同的处理。
当有实数根时,分别用r[1]和r[2]保存所得到的两个实数根。
intseekRoot(double[]r);
(5)按照a*x**2+b*x+c的格式(x2用x**2表示)输出二次多项式,在输出时要注意去掉系数为0的项,并且当b和c的值为负时,其前不能出现加号。
voidprint();
请写出上面的抽象数据类型所对应的Java类。
抽象数据类型如下:
ADTQuadraticis
Data:
doublea,b,c;//二次项、一次项和常数项系数
Operations:
publicQuadratic(doubleaa,doublebb,doublecc);//构造函数
publicQuadraticadd(Quadraticq);//二次多项式相加
publicdoublevalue(doublex);//二次多项式求值
publicintseekRoot(double[]r);//二次多项式方程求解
publicvoidprint();//输出二次多项式
endQuadratic
Java类参考答案如下:
publicclassQuadratic
{
privatedoublea,b,c;
publicQuadratic(doubleaa,doublebb,doublecc){
a=aa;b=bb;c=cc;
}
publicQuadraticadd(Quadraticq){
Quadraticqq=newQuadratic(0,0,0);
qq.a=a+q.a;
qq.b=b+q.b;
qq.c=c+q.c;
returnqq;
}
publicdoublevalue(doublex){
returna*x*x+b*x+c;
}
publicintseekRoot(double[]r){
if(a==0)return-1;//不是二次方程返回-1
doublex=b*b-4*a*c;
if(x>=0){
r[1]=(-b+Math.sqrt(x))/(2*a);
r[2]=(-b-Math.sqrt(x))/(2*a);
return1;//有实数根返回1
}
else
return0;//有虚数根返回0
}
publicvoidprint(){
if(a!
=0.0)//输出二次项
System.out.print(a+"*x**2");
if(b!
=0.0)//输出一次项
if(b>0)System.out.print("+"+b+"*x");
elseif(b<0)System.out.print(b+"*x");
if(c!
=0.0)//输出常数项
if(c>0)System.out.print("+"+c);
elseif(c<0)System.out.print(c);
System.out.println();
}
}
用于调试的主函数类如下:
publicclassChap1_x2
{
publicstaticvoidmain(String[]args)
{
doublea1=3,b1=5,c1=-2;
doublea2=1,b2=6,c2=5;
Quadraticq1=newQuadratic(a1,b1,c1);
Quadraticq2=newQuadratic(a2,b2,c2);
Quadraticq3;
q3=q1.add(q2);
doublex=q1.value
(2);
double[]r=newdouble[3];
intt1=q1.seekRoot(r);
if(t1==-1)System.out.println("不是二次方程!
");
elseif(t1==0)System.out.println("有虚数根!
");
elseSystem.out.println("有实数根!
");
q1.print();
q2.print();
q3.print();
System.out.println(x+""+r[1]+""+r[2]);
}
}
运行结果如下:
D:
\xuxk>javacQuadratic.java
D:
\xuxk>javacChap1_x2.java
D:
\xuxk>javaChap1_x2
有实数根!
3.0*x**2+5.0*x-2.0
1.0*x**2+6.0*x+5.0
4.0*x**2+11.0*x+3.0
20.00.3333333333333333-2.0
第二章集合
习题二
2.1选择题
1.在一个长度为n的顺序存储的集合中查找值为x的元素时,在等概率情况下,查找成功时的平均查找长度为()。
A.nB.n/2C.(n+1)/2D.(n-1)/2
2.在一个长度为n的链接存储的集合中查找值为x的元素时,算法的时间复杂度为()。
A.O
(1)B.O(n)C.O(n*n)D.O(log2n)
3.已知一个元素x不属于一个长度为n的顺序或链接存储的集合set中的元素,在插入前若省去顺序查找过程而直接进行插入,则算法的时间复杂度为()。
A.O
(1)B.O(log2n)C.O(n)D.O(n*n)
4.从一个长度为n的顺序或链接存储的集合set中删除值为obj的一个元素时,其平均时间复杂度为()。
A.O
(1)B.O(log2n)C.O(n)D.O(n*n)
5.从一个长度为n的链接存储的集合S中删除表头结点的时间复杂度为()。
A.O(n*n)B.O(log2n)C.O(n)D.O
(1)
6.从顺序存储的集合中删除一个元素时,其空出的位置由()元素填补。
A.表头B.表尾C.前驱D.后继
2.2填空题
1.向顺序存储的集合中插入元素是把该元素插入到________。
2.向链接存储的集合中插入元素是把该元素的结点插入到________。
3.从顺序存储的集合中删除一个元素时只需要移动________个元素。
4.求顺序或链接集合长度算法的时间复杂度为________。
5.由集合set1和集合set2的并运算得到的结果集合set,该集合的长度必然________set1和set2中任一个集合的长度。
6.由集合set1和集合set的交运算得到的结果集合set,该集合的长度必然__________set1和set2中任一个集合的长度。
7.设集合set的长度为n,则判断x是否属于集合set的时间复杂度为__________。
8.设集合set1和集合set2的长度分别为n1和n2,则进行并运算的时间复杂度为__________。
9.设集合set1和集合set2的长度分别为n1和n2,则进行交运算的时间复杂度为__________。
10.在集合的链接存储中,表头指针head所指向的结点为__________。
2.3运算题
1.假定一个集合S={23,56,12,49,35}采用顺序存储,若按照教材中的相应算法先向它插入元素72,再从中删除元素56,写出运算后得到的集合S。
2.假定一个集合S={23,56,12,49,35,48}采用顺序存储,若按照教材中的相应算法依次从中删除元素56和23,写出运算后得到的集合S。
3.假定一个集合S={23,56,12,49,35}采用链接存储,若按照教材中的相应算法插入62和删除23,写出运算后得到的集合S。
4.假定集合S1={23,56,12,49,35}和集合S2={23,12,60,38}均采用顺序存储,若按照教材中集合并运算的算法对S1和S2进行并运算,写出并运算后的结果集合。
5.假定集合S1={23,56,12,49,35}和集合S2={23,12,60,38}均采用顺序存储,若按照教材中集合交运算的算法对S1和S2进行交运算,写出交运算后的结果集合。
2.4算法设计题
1.修改从顺序存储的集合中删除元素的算法,要求当删除一个元素后检查数组空间的大小,若空间利用率小于40%同时数组长度大于maxSize时则释放数组的一半存储空间。
2.编写顺序存储集合类sequenceSet中的构造方法,它包含有一维数组参数Object[]a,该方法中给setArray数组分配的长度是a数组长度的1.5倍,并且根据a数组中的所有不同的元素值建立一个集合。
3.编写一个静态成员方法,返回一个顺序存储的集合set中所有元素的最大值,假定元素类型为Double。
4.编写顺序存储集合类sequenceSet中的复制构造方法,它包含有一个参数为Setset,实现把set所指向的顺序集合的内容复制到当前集合中的功能。
5.编写一个静态成员方法,实现两个顺序存储集合的差运算,并返回所求得的差集。
6.编写一个静态成员方法,实现两个链接存储集合的差运算,并返回所求得的差集。
2.1选择题
1.C2.B3.A4.C5.D6.B
2.2填空题
1.表尾2.表尾3.14.O
(1)5.大于等于
6.小于等于7.O(n)8.O(n1*n2)9.O(n1*n2)10.附加头结点
2.3运算题
1.S={23,72,12,49,35}
2.S={35,48,12,49}
3.S={56,12,49,35,62}
4.{23,56,12,49,35,60,38}
5.{23,12}
2.4算法设计题
1.
publicbooleanremove(Objectobj)//从集合删除一个元素
{
inti;
for(i=0;iif(setArray[i].equals(obj))break;//查找成功退出此循环
if(isetArray[i]=setArray[length-1];
//把集合中最后一个元素赋给被删除元素的位置
length--;
intms=setArray.length;
if((double)length/ms<0.4&&ms>maxSize){
Object[]p=newObject[ms/2];
for(intj=0;jsetArray=p;
}
returntrue;//删除成功返回真
}
elsereturnfalse;//删除失败返回假
}
提示:
在原来的删除算法remove中的length--语句的下面增加如下两条语句。
intms=setArray.length;
if((double)length/ms<0.4&&ms>maxSize){
Object[]p=newObject[ms/2];
for(intj=0;jsetArray=p;
}
2.
publicsequenceSet(Object[]a)
{
length=0;
setArray=newObject[(int)(a.length*1.5)];
for(inti=0;iintj;
for(j=0;jif(setArray[j].equals(a[i]))break;
if(j==length){setArray[length]=a[i];length++;}
}
}
3.
publicstaticObjectmaxValue(Setset)
{
sequenceSetdset=(sequenceSet)set;
if(dset.size()==0)returnnull;
Doublex=(Double)dset.value
(1);
for(inti=1;iDoubley=(Double)dset.value(i+1);
if(pareTo(x)>0)x=y;
}
returnx;
}
4.
publicsequenceSet(Setset)
{
sequenceSetdset=(sequenceSet)set;
setArray=newObject[dset.setArray.length];
for(inti=0;isetArray[i]=dset.setArray[i];
length=dset.length;
}
5.
publicstaticSetdifference(Setset1,Setset2)
{
sequenceSetdset2=(sequenceSet)set2;
sequenceSet1dset3=newsequenceSet(set1);
for(inti=0;ireturndset3;
}
6.
publicstaticSetdifference1(Setset1,Setset2)
{
linkSetdset1=(linkSet)set1;
linkSetdset2=(linkSet)set2;
linkSetdset3=newlinkSet();
for(inti=0;ifor(inti=0;ireturndset3;
}
第三章线性表
习题三
3.1单选题
1.在一个长度为n的顺序存储的线性表中,向第i个元素(1≤i≤n+1)位置插入一个新元素时,需要从后向前依次后移()个元素。
A.n-iB.n-i+1C.n-i-1D.i
2.在一个长度为n的顺序存储的线性表中,删除第i个元素(1≤i≤n)时,需要从前向后依次前移()个元素。
A.n-iB.n-i+1C.n-i-1D.i
3.在一个长度为n的线性表中顺序查找值为x的元素时,在等概率情况下,查找成功时的平均查找长度(即需要比较的元素个数)为()。
A.nB.n/2C.(n+1)/2D.(n-1)/2
4.在一个长度为n的线性表中,删除值为x的元素时需要比较元素和移动元素的总次数为()。
A.(n+1)/2B.n/2C.nD.n+1
5.在一个顺序表的表尾插入一个元素的时间复杂度为()。
A.O(n)B.O
(1)C.O(n*n)D.O(log2n)
6.若一个结点的引用为p,在p结点后面插入一个值为x的新结点的操作为()。
A.p=newNode(x,p)B.p=newNode(x,p.next)
C.p.next=newNode(x,p)D.p.next=newNode(x,p.next)
7.若一个结点的引用为p,它的前驱结点的引用为q,则删除p的后继结点的操作为()。
A.p=p.next.nextB.p.next=p.next.next
C.q.next=p.nextD.q.next=q.next.next
8.假定一个多项式中x的最高次幂为n,则在保存所有系数项的线性表表示中,其线性表长度为()。
A.n+1B.nC.n-1D.n+2
3.1单选题
1.B2.A3.C4.C5.B6.D7.B8.A
3.2填空题
1.对于当前长度为n的线性表,共包含有________多个插入元素的位置,共包含有________多个删除元素的位置。
2.若经常需要对线性表进行表尾插入和删除运算,则最好采用________存储结构,若经常需要对线性表进行表头插入和删除运算,则最好采用________存储结构。
3.由n个元素生成一个顺序表,若每次都调用插入算法把一个元素插入到表头,则整个算法的时间复杂度为________,若每次都调用插入算法把一个元素插入到表尾,则整个算法的时间复杂度为________。
4.由n个元素生成一个单链表,若每次都调用插入算法把一个元素插入到表头,则整个算法的时间复杂度为________,若每次都调用插入算法把一个元素插入到表尾,则整个算法的时间复杂度为________。
5.对于一个长度为n的顺序存储的线性表,在表头插入元素的时间复杂度为________,在表尾插入元素的时间复杂度为________。
6.对于一个单链接存储的线性表,在表头插入结点的时间复杂度为________,在表尾插入结点的时间复杂度为________。
7.在线性表的单链接存储中,若一个元素所在结点的引用为p,结点的类型为Node,则其后继结点的引用为________。
8.从一个顺序表和单链表中访问任一个给定位置序号的元素(结点)的时间复杂度分别为________和_______。
9.在多项式的线性表表示中,有两种表示方法,对应的线性表中的元素分别包含有________和_______个数据项。
10.假定一个稀疏矩阵具有m行、n列和t个非0元素,在对它进行快速转置的算法中,使用了两个整型数组num和pot,其中num的所有元素值之和为________,pot[1]的值为_______。
3.2填空题
1.n+1、n2.顺序、链接
3.O(n2)O(n)4.O(n)O(n2)
5.O(n)O
(1)6.O
(1)O(n)
7.p.next8.O
(1)O(n)
9.1、210.t、1
3.3写出下面主控程序类Chap3_13中的每个静态成员方法的功能并给出程序运行结果
publicclassChap3_13
{
publicstaticComparableminimum(sequenceListlist)
{
if(list.size()==0)returnnull;
Comparablemin=(Comparable)list.value
(1);
for(inti=2;i<=list.size();i++){
Comparablex=(Comparable)list.value(i);
if(pareTo(min)<0)min=x;
}
returnmin;
}
功能:
求出并返回顺序存储的list线性表中所有元素的最小值。
publicstaticvoidseparate(sequenceListlist,Comparablecom)
{
intn=list.size();
if(n==0||n==1)return;
inti=1,j=n;
while(i<=j){
while((i<=j)&&((Comparable)list.value(i)).compareTo(com)<0)i++;
while((i<=j)&&((Comparable)list.value(j)).compareTo(com)>=0)j--;
if(iComparablex=(Comparable)list.value(i);
list.modify(list.value(j),i);
list.modify(x,j);
i++;j--;
}
}
}
功能:
重新调整顺序存储的线性表list中元素值的排列次序,使得前面的元素都小于参数com的值,后面的元素都大于等于参数com的值。
调整的方法是分别