17.上三角矩阵中,主对角线上第r(1rn)行有n-r+1个元素,aij所在行的元素数是j-i+1。
所以,元素在一维数组的下标k和二维数组下标关系:
k=((i-1)*(2n-i+2))/2+(j-i+1)=(i-1)(2n-i)/2+j(ij)
18.9319.i(i-1)/2+j20.线性表21.其余元素组成的表
22.
(1)原子(单元素)是结构上不可再分的,可以是一个数或一个结构;而表带结构,本质就是广义表,因作为广义表的元素故称为子表。
(2)大写字母(3)小写字母(4)表中元素的个数(5)表展开后所含括号的层数
23.深度24.
(1)()
(2)(())(3)2(4)2
25.head(head(tail(tail(head(tail(tail(A)))))))
26.表展开后所含括号的层数27.
(1)5
(2)3
28.head(head(tail(LS)))29.head(tail(tail(head(tail(head(A))))))
30.head(tail(head(tail(H))))31.(b)32.(x,y,z)33.(d,e)
34.GetHead(GetHead(GetTail(L)))
35.本算法中,首先数组b中元素以逆置顺序放入d数组中,然后数组a和数组d的元素比较,将大者拷贝到数组c。
第一个WHILE循环到数组a或数组d结尾,第二个和第三个WHILE语句只能执行其中的一个。
(1)b[m-i+1]
(2)x:
=a[i](3)i:
=i+1(4)x:
=d[j](5)j:
=j+1(6)k:
=k+1(7)i<=l(8)j<=m
36.
(1)(i==k)return
(2)i+1(3)i-1(4)i!
=k
本算法利用快速排序思想,找到第k个元素的位置(下标k-1因而开初有k--)。
内层do循环以t(t=a[low])为“枢轴”找到其应在i位置。
这时若i等于k,则算法结束。
(即第一个空格处if(i==k)return)。
否则,若ik,则在low到i-1间去找,直到找到i=k为止。
37.逆置广义表的递归模型如下
f(LS)=
上面appEND(a,b)功能是将广义表a和b作为元素的广义表连接起来。
(1)(p->tag==0)//处理原子
(2)h=reverse(p->val.ptr.hp)//处理表头
(3)(p->val.ptr.tp)//产生表尾的逆置广义表
(4)s->val.ptr.tp=t;//连接
(5)q->val.ptr.hp=h//头结点指向广义表
38.本题要求将1,2,...,n*n个自然数,按蛇型方式存放在二位数组A[n][n]中。
“蛇型”方式,即是按“副对角线”平行的各对角线,从左下到右上,再从右上到左下,存放n2个整数。
对角线共2n-1条,在副对角线上方的对角线,题目中用k表示第k条对角线(最左上角k=1),数组元素x和y方向坐标之和为k+1(即题目中的i+j=k+1)。
副对角线下方第k条对角线与第2n-k条对角线对称,其元素的下标等于其对称元素的相应坐标各加(k-n)。
(1)k<=2*n-1//共填2*n-1条对角线
(2)q=2*n-k//副对角线以下的各条对角线上的元素数
(3)k%2!
=0//k为偶数时从右上到左下,否则从左下向右上填数。
(本处计算下标i和j)
(4)k>=n//修改副对角线下方的下标i和j。
(5)m++;或m=m+1//为填下个数作准备,m变化范围1..n*n。
本题解法的另一种思路见本章算法设计题第9题。
39.本题难点有二:
一是如何求下一出圈人的位置,二是某人出圈后对该人的位置如何处理。
按题中要求,从第s个人开始报数,报到第m个人,此人出圈。
n个人围成一圈,可看作环状,则下个出圈人,其位置是(s+m-1)%n。
n是人数,是个变量,出圈一人减1,算法中用i表示。
对第二个问题,算法中用出圈人后面人的位置依次前移,并把出圈人的位置(下标)存放到当时最后一个人的位置(下标)。
算法最后打印出圈人的顺序。
(1)(s+m-1)MODi//计算出圈人s1
(2)s1:
=i//若s1=0,说明是第i个人出圈(i%i=0)
(3)s1TOi-1//从s1到i依次前移,使人数减1,并将出圈人放到当前最后一个位置A[i]=w。
40.若第n件物品能放入背包,则问题变为能否再从n-1件物品中选出若干件放入背包(这时背包可放入物品的重量变为s-w[n])。
若第n件物品不能放入背包,则考虑从n-1件物品选若干件放入背包(这时背包可放入物品仍为s)。
若最终s=0,则有一解;否则,若s<0或虽然s>0但物品数n<1,则无解。
(1)s-w[n],n-1//Knap(s-w[n],n-1)=true
(2)s,n-1//Knap←Knap(s,n-1)
四、应用题
1、958三维数组以行为主序存储,其元素地址公式为:
LOC(Aijk)=LOC(Ac1c2c3)+[(i-c1)V2V3+(j-c2)V3+(k-c3)]*L+1
其中ci,di是各维的下界和上界,Vi=di-ci+1是各维元素个数,L是一个元素所占的存储单元数。
2.b对角矩阵的b条对角线,在主对角线上方和下方各有b/2条对角线(为叙述方便,下面设a=b/2)。
从第1行至第a行,每行上的元素数依次是a+1,a+2,...,b-2,b-1,最后的a行上的元素个数是b-1,b-2,...,a+1。
中间的(n-2a)行,每行元素个数都是b。
故b条对角线上元素个数为(n-2a)b+a*(a+b)。
存放在一维数组V[1..nb-a(b-a)]中,其下标k与元素在二维数组中下标i和j的关系为:
k=
3.每个元素32个二进制位,主存字长16位,故每个元素占2个字长,行下标可平移至1到11。
(1)242
(2)22(3)s+182(4)s+142
4.1784(公式:
Loc(Aijkl)=100(基地址)+[(i-c1)v2v3v4+(j-c2)v3v4+(k-c3)v4+(l-c4)]*4
5.1210+108L(LOC(A[1,3,-2])=1210+[(k-c3)v2v1+(j-c2)v1+(i-c1)]*L(设每个元素占L个存储单元)
6.数组占的存储字节数=10*9*7*4=2520;A[5,0,7]的存储地址=100+[4*9*7+2*7+5]*4=1184
7.五对角矩阵按行存储,元素在一维数组中下标(从1开始)k与i,j的关系如下:
k=
A[15,16]是第71个元素,在向量[-10:
m]中的存储位置是60。
8.
(1)540
(2)108(3)i=3,j=10,即A[3,10]9.k=i(i-1)/2+j
10.稀疏矩阵A有t个非零元素,加上行数mu、列数nu和非零元素个数tu(也算一个三元组),共占用三元组表LTMA的3(t+1)个存储单元,用二维数组存储时占用m*n个单元,只有当3(t+1)解不等式得t11.参见10。
12.题中矩阵非零元素用三元组表存储,查找某非零元素时,按常规要从第一个元素开始查找,属于顺序查找,时间复杂度为O(n)。
若使查找时间得到改善,可以建立索引,将各行行号及各行第一个非零元素在数组B中的位置(下标)偶对放入一向量C中。
若查找非零元素,可先在数组C中用折半查找到该非零元素的行号,并取出该行第一个非零元素在B中的位置,再到B中顺序(或折半)查找该元素,这时时间复杂度为O(logn)。
13.
(1)176
(2)76和108(3)28和116。
14.
(1)k=3(i-1)(主对角线左下角,即i=j+1)
k=3(i-1)+1(主对角线上,即i=j)
k=3(i-1)+2(主对角线上,即i=j-1)
由以上三式,得k=2(i-1)+j(1i,jn;1k3n-2)
(2)103*103-(3*103-2)
15.稀疏矩阵A采用二维数组存储时,需要n*n个存储单元,完成求Σaii(1<=i<=n)时,由于a[i][i]随机存取,速度快。
但采用三元组表时,若非零元素个数为t,需3(t+1)个存储单元(第一个分量中存稀疏矩阵A的行数,列数和非零元素个数,以后t个分量存各非零元素的行值、列值、元素值),比二维数组节省存储单元;但在求Σaii(1<=i<=n)时,要扫描整个三元组表,以便找到行列值相等的非零元素求和,其时间性能比采用二维数组时差。
16.特殊矩阵指值相同的元素或零元素在矩阵中的分布有一定规律,因此可以对非零元素分配单元(对值相同元素只分配一个单元),将非零元素存储在向量中,元素的下标i和j和该元素在向量中的下标有一定规律,可以用简单公式表示,仍具有随机存取功能。
而稀疏矩阵是指非零元素和矩阵容量相比很小(t<用十字链表作存储结构自然失去了随机存取的功能。
即使用三元组表的顺序存储结构,存取下标为i和j的元素时,要扫描三元组表,下标不同的元素,存取时间也不同,最好情况下存取时间为O
(1),最差情况下是O(n),因此也失去了随机存取的功能。
17.一维数组属于特殊的顺序表,和有序表的差别主要在于有序表中元素按值排序(非递增或非递减),而一维数组中元素没有按元素值排列顺序的要求。
18.n(n+1)/2(压缩存储)或n2(不采用压缩存储)
19.LOC(A[i,j])=LOC(A[3,2])+[(i-3)*5+(j-2)]×2(按行存放)
LOC(A[i,j])=LOC(A[3,2])+[(j-2)*6+(i-3)]×2(按列存放)
20.n阶下三角矩阵元素A[i][j](1<=i,j<=n,i>=j)。
第1列有n个元素,第j列有n-j+1个元素,第1列到第j-1列是等腰梯形,元素数为(n+(n-j+2)(j-1)/2,而aij在第j列上的位置是为i-j+1。
所以n阶下三角矩阵A按列存储,其元素aij在一维数组B中的存储位置k与i和j的关系为:
k=(n+(n-(j-1)+1)(j-1)/2+(i-j+1)=(2n-j)(j-1)/2+i
21.三对角矩阵第一行和最后一行各有两个非零元素,其余每行均有三个非零元素,所以共有3n-2个元素。
(1)主对角线左下对角线上的元素下标间有i=j+1关系,k与i和j的关系为k=3(i-1);主对角线上元素下标间有关系i=j,k与i和j的关系为k=3(i-1)+1;主对角线右上那条对角线上元素下标间有关系i=j-1,k与i和j的关系为k=3(i-1)+2。
综合以上三等式,有k=2(i-1)+j(1<=i,j<=n,|i-j|<=1)
(2)i=k/3+1;(1≤k≤3n-2)//k/3取小于k/3的最大整数。
下同
j=k-2(i-1)=k-2(k/3)=k%3+k/3
22.这是一个递归调用问题,运行结果为:
DBHEAIFJCKGL
23.
(1)FOR循环中,每次执行PerfectShuffle(A,N)和CompareExchange(A,N)的结果:
第1次:
A[1..8]=[90,30,85,65,50,80,10,100]
A[1..8]=[30,90,65,85,50,80,10,100]
第2次:
A[1..8]=[30,50,90,80,65,10,85,100]
A[1..8]=[30,50,80,90,10,65,85,100]
第3次:
A[1..8]=[30,10,50,65,80,85,90,100]
A[1..8]=[10,30,50,65,80,85,90,100]
(2)Demo的功能是将数组A中元素按递增顺序排序。
(3)PerfectShuffle中WHILE循环内是赋值语句,共2N次,WHILE外成组赋值语句,相当2N个简单赋值语句;CompareExchange中WHILE循环内是交换语句,最好情况下不发生交换,最差情况下发生N次交换,相当于3N个赋值语句;Demo中FOR循环循环次数log22N,故按赋值语句次数计算Demo的时间复杂度为:
最好情况:
O(4N*log22N)≈O(Nlog(2*N));最差情况:
O((4N+3N)*log22N)≈O(Nlog(2*N))。
24.这是一个排序程序。
运行后B数组存放A数组各数在排序后的位置。
结果是:
A={121,22,323,212,636,939,828,424,55,262}
B={3,1,6,4,8,10,9,7,2,5}
C={22,55,121,212,262,323,424,639,828,939}
25.
(1)c=
(2)a=
26.
(1)同上面26题
(1)
(2)对c数组的赋值同所选择的下标i和j的次序(指外层循环用j内层用i)没有关系
(3)同上题26
(2)
(4)对i,j下标取反序后,重复执行第(3)步,A数组所有元素均变为2。
(在机器上验证,反复循环3次后,所有元素均变为2)
27.错误有以下几处:
(1)过程参数没有类型说明;
(2)出错条件判断:
缺少OR(i+k>last+1);
(3)删除元素时FOR循环应正向,不应用反向DOWNTO;(4)count没定义;
低效体现在两处:
(1)删除k个元素时,不必一个一个元素前移,而应一次前移k个位置;
(2)last指针不应一次减1,而应最后一次减k。
正确的高效算法如下:
constm=64;
TYPEARR=ARRAY[1..m]OFinteger;
PROCEDUREdelk(VARA:
ARR;VARlast:
integer;i,k:
integer);
{从数组A[1..last]中删除第i个元素起的k个元素,m为A的上限}
VARcount:
integer;
BEGIN
IF(i<0)OR(i>last)OR(k<0)OR(last>m)OR(i+k>last+1)
THENwrite(’error’)
ELSE[FORcount:
=i+kTOlastDOA[count-k]:
=A[count];
last:
=last-k;]
END;
28.这是计数排序程序。
(a)c[i](1<=i<=n)中存放A数组中值为i的元素个数。
(b)c[i](1<=i<=n)中存放A数组中小于等于i的个数。
(c)B中存放排序结果,B[1..n]已经有序。
(d)算法中有4个并列for循环语句,算法的时间复杂度为O(n)。
29.上三角矩阵第一行有n个元素,第i-1行有n-(i-1)+1个元素,第一行到第i-1行是等腰梯形,而第i行上第j个元素(即aij)是第i行上第j-i+1个元素,故元素Aij在一维数组中的存储位置(下标k)为:
k=(n+(n-(i-1)+1))(i-1)/2+(j-i+1)=(2n-i+2)(i-1)/2+j-i+1
30.将上面29题的等式进一步整理为:
k=(n+1/2)i-i2/2+j-n,
则得f1(i)=(n+1/2)i-i2/2,f2(j)=j,c=-n。
31.
(1)将对称矩阵对角线及以下元素按行序存入一维数组中,结果如下:
(2)因行列表头的“行列域”值用了0和0,下面十字链表中行和列下标均从1开始。
注:
上侧列表头Hi和左侧行表头Hi是一个(即H1、H2、H3和H4),为了清楚,画成了两个。
32.
(1)k=(2n-j+2)(j-1)/2+i-j+1(当i≥j时,本题n=4)
k=(2n-i+2)(i-1)/2+j-i+1(当i(2)稀疏矩阵的三元组表为:
s=((4,4,6),(1,1,1),(1,4,2),(2,2,3),(3,4,5),(4,1,2),(4,3,5)。
其中第一个三元组是稀疏矩阵行数、列数和非零元素个数。
其它三元组均为非零元素行值、列值和元素值。
33.
(1)k=2(i-1)+j(1≤i,j≤n,|i-j|≤1)
i=floor(k/3)+1//floor(a)是取小于等于a的最大整数
j=k-2(i-1)
推导过程见上面第25题。
(2)行逻辑链接顺序表是稀梳矩阵压缩存储的一种形式。
为了随机存取任意一行的非零元,需要知道每一行第一个非零元在三元组表中的位置。
为此,除非零元的三元组表外,还需要一个向量,其元素值是每行第一个非零元在三元组表中的位置。
其类型定义如下:
typedefstruct
{intmu,nu,tu;//稀梳矩阵的行数、列数和非零元素个数
intrpos[maxrow+1];//行向量,其元素值是每行第一个非零元在三元组表中的位置。
Tripledata[maxsize];
}SparsMatrix;
因篇幅所限,不再画出行逻辑链接顺序表。
34.各维的元素数为di-ci+1,则a[i1,i2,i3]的地址为:
a0+[(i1-c1)(d3-c3+1)(d2-c2+1)+(i2-c2)(d2-c2+1)+(i3-c3)]*L
35.主对角线上元素的坐标是i=j,副对角线上元素的坐标i和j有i+j=n+1的关系
(1)i=j或i=n+1-j(1≤i,j≤n)
(2)非零元素分布在两条主、副对角线上,除对角线相交处一个元素(下称“中心元素”)外,其余每行都有两个元素。
主对角线上的元素,在向量B中存储的下标是k=2i-1(i=j,1≤i,j≤n,1<=k<=2n-1)。
副对角线上的元素,在中心元素前,在向量B中存储的下标是k=2i(i<>j,1≤i,j≤n/2);在中心元素后,其下标是k=2(i-1)(i<>j,n/2+1≤i,j≤n,1<=k<=2n-1)。
(3)aij在B中的位置K=
36.由于对称矩阵采用压缩存储,上三角矩阵第一列一个元素,第二列两个元素,第j列j个元素。
上三角矩阵共有n(n+1)/2个元素。
我们将这些元素存储到一个向量B[n(n+1)/2+1]中。
可以看到B[k]和矩阵中的元素aij之间存在着一一对应关系:
则其对应关系可表示为:
k=(1<=i,j<=n,1<=k<=n(n+1)/2)
intMAX(intx,inty)
{return(x>y?
x:
y);
}
intMIN(intx,inty)
{return(xx:
y);
}
37.设用mu,nu和tu表示稀疏矩阵行数,列数和非零元素个数,则转置矩阵的行数,列数和非零元素的个数分别是nu,mu和tu。
转置可按转置矩阵的三元组表中的元素顺序进行,即按稀疏矩阵的列序,从第1列到第nu列,每列中按行值递增顺序,找出非零元素,逐个放入转置矩阵的三元组表中,转时行列值互换,元素值复制。
按这种方法,第1列到第1个非零元素一定是转置后矩阵的三元组表中的第1个元素,第1列非零元素在第2列非零元素的前面。
这种方法时间复杂度是O(n*P),其中p是非零元素个数,当p和m*n同量级时,时间复杂度为O(n3)。
另一种转置方法称作快速转置,使时间复杂度降为O(m*n)。
它是按稀疏矩阵三元组表中元素的顺序进行。
按顺序取出一个元素,放到转置矩阵三元组表的相应位置。
这就要求出每列非零元素个数和每列第一个非零元素在转置矩阵三元组表中的位置,设置了两个附加向量。
38.广义表中的元素,可以是原子,也可以是子表,即广义表是原子或子表的有限序列,满足线性结构的特性:
在非空线性结构中,只有一个称为“第一个”的元素,只有一个成为“最后一个”的元素,第一元素有后继而没有前驱,最后一个元素有前驱而没有后继,其余每个元素有唯一前驱和唯一后继。
从这个意义上说,广义表属于线性结构。
39.数组是具有相同性质的数据元素的集合,同时每个元素又有唯一下标限定,可以说数组是值和下标偶对的有限集合。
n维数组中的每个元素,处于n个关系之中,每个关系都是线性的,且n维数组可以看作其元素是n-1维数组的一个线性表。
而广义表与线性表的关系,见上面38题的解释。
40.线性表中的元素可以是各种各样的,但必须具有相同性质,属于同一数据对象。
广义表中的元素可以是原子,也可以是子表。
其它请参见38
41.
(1)(c,d)
(2)(b)(3)b(4)(f)(5)()
42.Head(Tail(Head(Head(L1))))
Head(Head(Head(Tail(Head(Tail(L2))))))
类似本题的另外叙述的几个题解答如下:
(1)head(head(tail(tail(L)))),设L=(a,(c),b),(((e))))
(2)head(head(