return'<';
elseif(A.elem[i]>B.elem[i]||i==B.length)
return'>';
}
2.13②试写一算法在带头结点的单链表结构上实现线性表操作
Locate(L,x)。
实现下列函数:
LinkListLocate(LinkListL,ElemTypex);
//If'x'inthelinkedlistwhoseheadnodeispointed
//by'L',thenreturnpointerpointingnode'x',
//otherwisereturn'NULL'
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
LinkListLocate(LinkList&L,ElemTypex)
//If'x'inthelinkedlistwhoseheadnodeispointed
//by'L',thenreturnpointerhapointingnode'x',
//otherwisereturn'NULL'
{
LinkListp;
inti=0;
p=L->next;
while(p->data!
=x&&p!
=NULL)
{
i++;
p=p->next;
}
returnp;
}
2.14②试写一算法在带头结点的单链表结构上实现线性表
操作Length(L)。
实现下列函数:
intLength(LinkListL);
//Returnthelengthofthelinkedlist
//whoseheadnodeispointedby'L'
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
intLength(LinkListL)
//Returnthelengthofthelinkedlist
//whoseheadnodeispointedby'L'
{
LinkListp;
inti=0;
p=L->next;
while(p!
=NULL)
{
i++;
p=p->next;
}
returni;
}
2.17②试写一算法,在无头结点的动态单链表上实现
线性表操作INSERT(L,i,b),并和在带头结点的动态单
链表上实现相同操作的算法进行比较。
实现下列函数:
voidInsert(LinkList&L,inti,ElemTypeb);
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
voidInsert(LinkList&L,inti,ElemTypeb)
{
LinkListp,q;
intj=2;
p=L;
while(j
{
j++;
p=p->next;
}
if(i!
=0&&i!
=1)
{
q=(LinkList)malloc(sizeof(LNode));
q->data=b;
q->next=p->next;
p->next=q;
}
if(i==1)
{
q=(LinkList)malloc(sizeof(LNode));
q->data=b;
q->next=p;
L=q;
}
}
2.18②同2.17题要求。
试写一算法,
实现线性表操作DELETE(L,i)。
实现下列函数:
voidDelete(LinkList&L,inti);
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
voidDelete(LinkList&L,inti)
{
LinkListp,q;
intj=2;
p=L;
while(j
=NULL)
{
j++;
p=p->next;
}
if(i!
=0&&i!
=1)
{
q=p->next;
p->next=q->next;
free(q);
}
if(i==1)
{
q=L;
L=L->next;
free(q);
}
}
2.20②同2.19题条件,试写一高效的算法,删除表中所
有值相同的多余元素(使得操作后的线性表中所有元素的
值均不相同)同时释放被删结点空间,并分析你的算法的
时间复杂度。
实现下列函数:
voidPurge(LinkList&L);
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
voidPurge(LinkList&L)
{
LinkListp,q;
inti=0;
p=L;
while(p!
=NULL&&p->next!
=NULL)
{
if(p->data==p->next->data)
{
q=p->next;
p->next=q->next;
free(q);
}
else
p=p->next;
}
}
◆2.21③试写一算法,实现顺序表的就地逆置,
即利用原表的存储空间将线性表(a1,a2,…,an)
逆置为(an,an-1,…,a1)。
实现下列函数:
voidInverse(SqList&L);
顺序表类型定义如下:
typedefstruct{
ElemType*elem;
intlength;
intlistsize;
}SqList;
voidInverse(SqList&L)
{
inti=0,j=0;
i=L.length/2;
for(j=0;j
{
ElemTypee=L.elem[j];
L.elem[j]=L.elem[L.length-j-1];
L.elem[L.length-j-1]=e;
}
}
◆2.22③试写一算法,对单链表实现就地逆置。
实现下列函数:
voidInverse(LinkList&L);
/*对带头结点的单链表L实现就地逆置*/
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
voidInverse(LinkList&L)
/*对带头结点的单链表L实现就地逆置*/
{
LinkListp,q,k;
q=p=L->next;
while(p->next!
=NULL)
{
k=q;
q=p->next;
p->next=q->next;
q->next=k;
}
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*/
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
voidMerge(LinkListha,LinkListhb,LinkList&hc)
/*依题意,合并带头结点的单链表ha和hb为hc*/
{
LinkListp,q,k,r;
p=ha->next;
q=hb->next;
if(p==NULL)hc=hb;
elseif(q==NULL)hc=ha;
else
{
while(p->next!
=NULL&&q->next!
=NULL)
{
k=p->next;
r=q->next;
p->next=q;
p=k;
q->next=p;
q=r;
}
if(p->next!
=NULL)
q->next=p->next;
p->next=q;
hc=ha;
}
}
◆2.24④假设有两个按元素值递增有序排列的线性表
A和B,均以单链表作存储结构,请编写算法将A表和B表
归并成一个按元素值递减有序(即非递增有序,允许表
中含有值相同的元素)排列的线性表C,并要求利用原
表(即A表和B表)的结点空间构造C表。
实现下列函数:
voidUnion(LinkList&lc,LinkListla,LinkListlb);
/*依题意,利用la和lb原表的结点空间构造lc表*/
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
voidUnion(LinkList&lc,LinkListla,LinkListlb)
{
LinkListpa=la->next;
LinkListpb=lb->next;
LinkListpre=NULL;
LinkListq,pc;
while(pa||pb)
{
if((pa->datadata&&pa!
=NULL)||pb==NULL)
{
pc=pa;
q=pa->next;
pa->next=pre;
pa=q;
}
else
{
pc=pb;
q=pb->next;
pb->next=pre;
pb=q;
}
pre=pc;
printf("%s","done");
}
lc=la;
la->next=pc;//构造新表头
/*LinkListpa=la->next;
LinkListpb=lb->next;
LinkListpc=la;
lc=la;
while(pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=pa?
pa:
pb;
free(lb);
//将c实现就地逆置'
LinkListp,q;
p=lc->next;
while(p->next)
{
q=p->next;
p->next=p->next->next;
q->next=lc->next;
lc->next=q;
}
*/
}
2.31②假设某个单向循环链表的长度大于1,且表
中既无头结点也无头指针。
已知s为指向链表中某个
结点的指针,试编写算法在链表中删除指针s所指结
点的前驱结点。
实现下列函数:
ElemTypeDeleteNode(LinkLists);
/*删除指针s所指结点的前驱结点,并返回被删结点的元素值*/
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
ElemTypeDeleteNode(LinkLists)
/*删除指针s所指结点的前驱结点,并返回被删结点的元素值*/
{
LinkListp;
p=s->next;
while(p->next->next!
=s)
p=p->next;
ElemTypee=p->next->data;
p->next=s;
returne;
}
2.32②已知有一个单向循环链表,其每个结点中
含三个域:
prev、data和next,其中data为数据域,
next为指向后继结点的指针域,prev也为指针域,
但它的值为空(NULL),试编写算法将此单向循环链
表改为双向循环链表,即使prev成为指向前驱结点
的指针域。
实现下列函数:
voidPerfectBiLink(BiLinkList&CL);
双向循环链表类型定义如下:
typedefstructBiNode{
ElemTypedata;
intfreq;//2.38题用
structBiNode*prev,
*next;
}BiNode,*BiLinkList;
voidPerfectBiLink(BiLinkList&CL)
{
BiLinkListp,q,k;
k=p=q=CL;
while(p->next!
=q)
{
p=p->next;
p->prev=k;
k=p;
}
q->prev=p;
}
◆2.33③已知由一个线性链表表示的线性表中含有
三类字符的数据元素(如:
字母字符、数字字符和其
它字符),试编写算法将该线性链表分割为三个循环
链表,其中每个循环链表表示的线性表中均只含一类
字符。
实现下列函数:
voidSplit(LinkList&lc,LinkList&ld,LinkList&lo,LinkListll);
单链表类型定义如下:
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
voidSplit(LinkList&A,LinkList&B,LinkList&C,LinkListL)
{
LinkLists,p,q,r;
s=L->next;
A=(LinkList)malloc(sizeof(LNode));p=A;
B=(LinkList)malloc(sizeof(LNode));q=B;
C=(LinkList)malloc(sizeof(LNode));r=C;//建立头结点
while(s)
{
if((s->data>='a'&&s->data<='z')||(s->data<='Z'&&s->data>='A'))
{
p->next=s;p=s;
}
elseif(s->data>='0'&&s->data<='9')
{
q->next=s;q=s;
}
else
{
r->next=s;r=s;
}
s=s->next;
}//while
p->next=A;q->next=B;r->next=C;//完成循环链表
}
2.37④设以带头结点的双向循环链表表示的线性
表L=(a1,a2,...,an)。
试写一时间复杂度为O(n)的
算法,将L改造为L=(a1,a3,...,an,...,a4,a2)。
实现下列函数:
voidReverseEven(BiLinkList&L);
双向循环链表类型定义如下:
typedefstructBiNode{
ElemTypedata;
intfreq;//2.38题用
structBiNode*prev,
*next;
}BiNode,*BiLinkList;
voidReverseEven(BiLinkList&L)
{
BiLinkListp=NULL;
p=L->next;
while(p->next!
=L&&p->next->next!
=L)
{
p->next=p->next->next;
p=p->next;
}//此时p指向最后一个奇数结点
if(p->next==L)p->next=L->prev->prev;
elsep->next=L->prev;
p=p->next;//此时p指向最后一个偶数结点
while(p->prev->prev!
=L)
{
p->next=p->prev->prev;
p=p->next;
}
if(p!
=L)
p->next=L;//按题目要求调整了next链的结构,此时pre链仍为原状
for(p=L;p->next!
=L;p=p->next)p->next->prev=p;
L->prev=p;//调整pre链的结构,同2.32方法
}
◆2.39③试对稀疏多项式Pn(x)采用存储量同多项式项
数m成正比的顺序存储结构,编写求Pn(x0)的算法(x0为
给定值),并分析你的算法的时间复杂度。
实现下列函数:
floatEvaluate(SqPolypn,floatx);
/*pn.data[i].coef存放ai,*/
/*pn.data[i].exp存放ei(i=1,2,...,m)*/
/*本算法计算并返回多项式的值。
不判别溢出。
*/
/*入口时要求0≤e1多项式的顺序存储结构:
typedefstruct{
intcoef;
intexp;
}PolyTerm;
typedefstruct{
PolyTerm*data;
intlength;
}SqPoly;
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以循环链表作存储结构,*/
/*将此链表修改成它的导函数,并释放无用结点*/
链式多项式的类型定义:
typedefstructPolyNode{
intcoef;