elseif(m==k-1)f=1;
else
{
for(i=0;i<=k-2;i++)temp[i]=0;
temp[k-1]=1;
for(i=k;i<=m;i++)
{
for(j=i-1;j>=i-k;j--)
sum=sum+temp[j];
temp[i]=sum;
sum=0;
}
f=temp[m];
}
returnOK;
}
1.18③假设有A、B、C、D、E五个高等院校进行田径对抗赛,
各院校的单项成绩均以存入计算机并构成一张表,表中每一行的形式为项目名称性别校名成绩得分.编写算法,处理上述表格,以统计各院校的男、女总分和团
体总分,并输出。
voidScores(ResultType*result,ScoreType*score)
/*求各校的男、女总分和团体总分,并依次存入数组score*/
/*假设比赛结果已经储存在result[]数组中,*/
/*并以特殊记录{"",male,'',"",0}(域scorce=0)*/
/*表示结束*/
{
inti=0;
while(result[i].sport)
{
switch(result[i].schoolname)
{
case'A':
score[0].totalscore+=result[i].score;
if(result[i].gender==female)
score[0].femalescore+=result[i].score;
else
score[0].malescore+=result[i].score;
break;
case'B':
score[1].totalscore+=result[i].score;
if(result[i].gender==female)
score[1].femalescore+=result[i].score;
else
score[1].malescore+=result[i].score;
break;
case'C':
score[2].totalscore+=result[i].score;
if(result[i].gender==female)
score[2].femalescore+=result[i].score;
else
score[2].malescore+=result[i].score;
break;
case'D':
score[3].totalscore+=result[i].score;
if(result[i].gender==female)
score[3].femalescore+=result[i].score;
else
score[3].malescore+=result[i].score;
break;
case'E':
score[4].totalscore+=result[i].score;
if(result[i].gender==female)
score[4].femalescore+=result[i].score;
else
score[4].malescore+=result[i].score;
break;
}
i++;
}
}
◆1.19④试编写算法,计算i!
×2^i的值并存入数组
a[0..ARRSIZE-1]的第i-1个分量中(i=1,2,…,n)。
假设计算机中允许的整数最大值为MAXINT,则当n>ARRSIZE或对某个k(1≤k≤n)使k!
×2^k>MAXINT时,应
按出错处理。
注意选择你认为较好的出错处理方法。
1.19
StatusSeries(intARRSIZE,inta[])
/*求i!
*2^i序列的值并依次存入长度为ARRSIZE的数组a;*/
/*若所有值均不超过MAXINT,则返回OK,否则返回OVERFLOW*/
{
inti=1;
intt=1;
a[0]=1;intn;
for(n=1;n{
i=i*n;
t=2*n;
a[i]=i*t;
}
for(i=0;i{
if(a[i]>MAXINT)
returnOVERFLOW;
break;
}
returnOK;
}
◆1.20④试编写算法求一元多项式
P(x)=a0+a1x+a2x^2+...+anx^n
的值P(x0),并确定算法中每一语句的执行次数和整个算法
的时间复杂度。
注意选择你认为较好的输入和输出方法。
1.20
floatPolynomial(intn,inta[],floatx)
/*求一元多项式的值P(x)。
*/
/*数组a的元素a[i]为i次项的系数,i=0,...,n*/
{inti;
floats=0;
for(i=n;i>=0;i--)
s=s*x+a[i];
returns;
}
第二章
◆2.11②设顺序表L中的数据元素递增有序。
试写一算法,将x插入到L的适当位置上,并保
持该表的有序性。
2.11
voidInsertOrderList(SqList&L,ElemTypex)
//在有序的顺序表L中保序插入数据元素x
{
intj;
j=L.length-1;
while(L.elem[j]>x)
{
L.elem[j+1]=L.elem[j];
j--;
}
L.elem[j+1]=x;
L.length++;
}
◆2.12③设A=(a1,…,am)和B=(b1,…,bn)均为有序顺序表,
A'和B'分别为A和B中除去最大共同前缀后的子表(例如,
A=(x,y,y,z,x,z),B=(x,y,y,z,y,x,x,z),则两者中最大
的共同前缀为(x,y,y,z),在两表中除去最大共同前缀后
的子表分别为A'=(x,z)和B'=(y,x,x,z))。
若A'=B'=空表,则A=B;若A'=空表,而B'≠空表,或者两者均不为空表,且A'的首元小于B'的首元,则AB。
试写一个比较A和B大小的算法。
(注意:
在算法中,不要破坏原表A和B,也不一定先求得A'和B'才进行比较)。
charCompare(SqListA,SqListB)
//比较顺序表A和B,
//返回'<',若A
//'=',若A=B;
//'>',若A>B
{
inti=0;
while((i<=A.length-1)&&(i<=B.length-1)&&(A.elem[i]=B.elem[i]))++i;
if(i==A.length&&i==B.length)return'=';
elseif(i==A.length&&i!
=B.length&&A.elem[i]elseif(i!
=A.length&&i!
=B.length&&A.elem[i]elsereturn'>';
}
2.13②试写一算法在带头结点的单链表结构上实现线性表操作
Locate(L,x)。
实现下列函数:
LinkListLocate(LinkListL,ElemTypex);
//If'x'inthelinkedlistwhoseheadnodeispointed
//by'L',thenreturnpointerpointingnode'x',
//otherwisereturn'NULL'
LinkListLocate(LinkList&L,ElemTypex)
//If'x'inthelinkedlistwhoseheadnodeispointed
//by'L',thenreturnpointerhapointingnode'x',
//otherwisereturn'NULL'
{
LinkListha;
ha=L->next;
while(ha!
=NULL&&ha->data!
=x)
ha=ha->next;
if(ha==NULL)
returnNULL;
elsereturnha;
}
2.14②试写一算法在带头结点的单链表结构上实现线性表操作Length(L)。
intLength(LinkListL)
//Returnthelengthofthelinkedlist
//whoseheadnodeispointedby'L'
{LinkListp;
inti=0;
p=L;
while(p->next!
=NULL)
{
p=p->next;
i++;
}
returni;
}
2.17②试写一算法,在无头结点的动态单链表上实现线性表操作INSERT(L,i,b),并和在带头结点的动态单链表上实现相同操作的算法进行比较。
voidInsert(LinkList&L,inti,ElemTypeb)
{
LinkListp,s;
if(!
L&&i==1)
{L=(LinkList)malloc(sizeof(LNode));
L->data=b;
L->next=NULL;
}
else
{if(i==0){}
elseif(i==1)
{
s=(LinkList)malloc(sizeof(LNode));
s->data=b;
s->next=L;
L=s;
}
else
{
p=L;intj=1;
while(p&&j{
p=p->next;
j++;
}
s=(LinkList)malloc(sizeof(LNode));
s->data=b;
s->next=p->next;
p->next=s;
}
}
}
2.18②同2.17题要求。
试写一算法,
实现线性表操作DELETE(L,i)。
voidDelete(LinkList&L,inti)
{
LinkListp,q;
if(i==0){}
elseif(i==1)
{
p=L;
L=L->next;
free(p);
}
else
{
intj=1;
p=L;
while(p->next!
=NULL&&j{
p=p->next;
j++;
}
q=p->next;
p->next=q->next;
free(q);
}
}
2.20②同2.19题条件,试写一高效的算法,删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)同时释放被删结点空间,并分析你的算法的时间复杂度。
voidPurge(LinkList&L)
{LinkListp,q;
p=L->next;
q=p->next;
while(q)
{
if(p->data==q->data)
{
q=q->next;
p->next=q;
}
q=q->next;
p=p->next;
}
}
◆2.21③试写一算法,实现顺序表的就地逆置,
即利用原表的存储空间将线性表(a1,a2,…,an)
逆置为(an,an-1,…,a1)。
voidInverse(SqList&L)
{
inttemp;
inti,j;
for(i=0,j=L.length-1;i<=j;i++,j--)
{
temp=L.elem[i];
L.elem[i]=L.elem[j];
L.elem[j]=temp;
}
}
◆2.22③试写一算法,对单链表实现就地置。
voidInverse(LinkList&L)
/*对带头结点的单链表L实现就地逆置*/
{
LinkListp,q,r;
p=L->next;q=NULL;
while(p)
{
r=q;
q=p;
p=p->next;
q->next=r;
}
L->next=q;
}
2.23③设线性表A=(a1,...,am),B=(b1,...,bn),试写一个按下列规则合并A、B为线性表C的算法,即使得C=(a1,b1,...,am,bm,bm+1,...,bn)当m≤n时;或者C=(a1,b1,...,an,bn,an+1,...,am)当m>n时。
线性表A、B和C均以单链表作存储结构,且C表利用A表和B表中的结点空间构成。
注意:
单链表的长度值m和n均未显式存储。
voidMerge(LinkListha,LinkListhb,LinkList&hc)
/*依题意,合并带头结点的单链表ha和hb为hc*/
{
LinkListpa,pb,pc;
pa=ha->next;pb=hb->next;pc=hc=ha;
while(pa&&pb)
{
pc->next=pa;pc=pa;pa=pa->next;
pc->next=pb;pc=pb;pb=pb->next;
}
while(pa)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
while(pb)
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
◆2.24④假设有两个按元素值递增有序排列的线性表A和B,均以单链表作存储结构,请编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许表中含有值相同的元素)排列的线性表C,并要求利用原表(即A表和B表)的结点空间构造C表。
voidUnion(LinkList&lc,LinkList&la,LinkList&lb)
{
LinkListp,q,s,t;
lc=la;p=la->next;q=lb->next;lc->next=NULL;
while(p&&q)
if(p->datadata)
{
s=p->next;p->next=lc->next;
lc->next=p;p=s;
}
else
{
t=q->next;q->next=lc->next;
lc->next=q;q=t;
}
while(p){s=p->next;p->next=lc->next;lc->next=p;p=s;}
while(q){t=q->next;q->next=lc->next;lc->next=q;q=t;}
free(lb);
}
2.31②假设某个单向循环链表的长度大于1,且表中既无头结点也无头指针。
已知s为指向链表中某个结点的指针,试编写算法在链表中删除指针s所指结点的前驱结点。
ElemTypeDeleteNode(LinkLists)
/*删除指针s所指结点的前驱结点,并返回被删结点的元素值*/
{
LinkListp,q;
nti;
p=s;
while(p->next->next!
=s)
p=p->next;
q=p->next;
i=q->data;
p->next=q->next;
free(q);
returni;
}
2.32②已知有一个单向循环链表,其每个结点中
含三个域:
prev、data和next,其中data为数据域,next为指向后继结点的指针域,prev也为指针域,但它的值为空(NULL),试编写算法将此单向循环链表改为双向循环链表,即使prev成为指向前驱结点的指针域。
voidPerfectBiLink(BiLinkList&CL)
{
BiLinkListp;
for(p=CL;!
p->next->prev;p=p->next)
p->next->prev=p;
}
◆2.33③已知由一个线性链表表示的线性表中含有三类字符的数据元素(如:
字母字符、数字字符和其它字符),试编写算法将该线性链表分割为三个循环链表,其中每个循环链表表示的线性表中均只含一类字符。
voidSplit(LinkList&lc,LinkList&ld,LinkList&lo,LinkListll)
{
LinkListp,q,r,s;
p=lc;q=lo;
r=ld,s=ll->next;
while(s)
{
if(s->data>='0'&&s->data<='9')
{
r->next=s;
r=r->next;
}
elseif(s->data>='A'&&s->data<='Z'||s->data>='a'&&s->data<='z')
{
p->next=s;
p=p->next;
}
else
{
q->next=s;
q=q->next;
}
s=s->next;
}
p->next=NULL;
q->next=NULL;
r->next=NULL;
}
2.37④设以带头结点的双向循环链表表示的线性表L=(a1,a2,...,an)。
试写一时间复杂度为O(n)的算法,将L改造为L=(a1,a3,...,an,...,a4,a2)。
voidReverseEven(BiLinkList&L)
{
BiLinkListp;
p=L->next;
if(p->next==L){}
else
{
while(p->next!
=L&&p->next->next!
=L)
{
p->next=p->next->next;
p=p->next;
}
if(p->next==L)p->next=L->prev->prev;
elsep->next=L->prev;
p=p->next;
while(p->prev->prev!
=L)
{
p->next=p->prev->prev;
p=p->next;
}
p->next=L;
for(p=L;p->next!
=L;p=p->next)p->next->prev=p;
L->prev=p;
}
}
◆2.39③试对稀疏多项式Pn(x)采用存储量同多项式项数m成正比的顺序存储结构,编写求Pn(x0)的算法(x0为给定值),并分析你的算法的时间复杂度。
floatf(floatx,intj)
{
inti;
floats=1;
for(i=0;is*=x;
}
returns;
}
floatEvaluate(SqPolypn,floatx)
/*pn.data[i].coef存放ai,*/
/*pn.data[i].exp存放ei(i=1,2,...,m)*/
/*本算法计算并返回多项式的值。
不判别溢出。
*/
/*入口时要求0≤e1{inti;
floats=0;
for(i=0;is+=pn.data[i].coef*f(x,pn.data[i].exp);
}
returns;
}
◆2.41②试以循环链表作稀疏多项式的存储结构,编写求其导函数的算法,要求利用原多项式中的结点空间存放其导函数(多项式),同时释放所有无用(被删)结点。
voidDifference(LinkedPoly&pa)
/*稀疏多项式pa以循环链表作存储结构,*/
/*将此链表修改成它的导函数,并释放无用结点*/
{
LinkedPolyp;
p=pa->next;
if(!
p->exp)
{
pa->next=p->next;
p=p->next;
}
while(p!
=pa)
{
p->coef=p->coef*p->exp;
p->exp--;
p=p->next;
}
}
第三章
◆3.17③试写一个算法,识别依次读入的一个以@为结束符的字符序列是否为形如'序列1&序列2'模式的字符序列。
其中序列1和序列2中都不含字符'&',且序列2是序列1的逆序列。
例如,'a+b&b+a'是属该模式的字符序列,而'1+3&3-1'则不是。
Statusmatch(char*str)
/*若str是属该模式的字符序列,*/
/*则返回TRUE,否则返回FALSE*/
{
SqStacks;
SElemTypee;
InitStack(s);
inti=0;
while(str[i]!
='&'&&str[i]!
='@')
{
Push(s,