【2.11】设计算法以删除链表中值为x的元素结点。
分析】与基本运算基本相同,只是这里要根据结点的元素值来搜索待删除目标结点的指针。与基本删除类似,我们用一个指针p指向待删除结点的前驱,则p->next指向目标结点。初始化时让p=l,即指向头结点。
循环将p->next->data与x进行比较,若相等,p->next指示的即是待删除结点。
此外,要处理x不在表中情况。
删除第一个x结点算法描述】
bool listdeletex(node* l, elementtype x)
node* u;
node* p=l; /指向头结点。
int succ=0; /是否删除成功标记,成功删除succ=1,失败succ=0。
while(p->next)
p=p->next;
if(succ==1)
return true; /成功删除,返回 true
elsereturn false; /删除失败,返回 false,x不在链表中。
算法分析】时间复杂度o(n)。
删除所有x结点算法描述】
bool listdeletex1(node* l, elementtype x)
node* u;
node* p=l; /p指向待删除结点的前驱,初始化指向头结点。
int succ=0; /是否删除成功标记,成功删除succ=1,失败succ=0。
while(p->next)
if(succ==1)
return true; /成功删除,返回 true
elsereturn false; /删除失败,返回 false,x不在链表中。
2.14】a、b为递增有序的带头结点的单链表,分别表示集合a和b。设计算法判断a是否b的子集。是,返回1;否,返回0。要求时间性能尽可能好。
解题分析】审题:a、b是集合,即没有重复元素。
简单的做法是使用通用判定子集方法:依次取a的每一个元素,判定是在b中,全在b中,a是b子集;若一个不在b中,则a不是b的子集。用二层循环实现,时间复杂度为o(|a|+|b|)。
这个方法没有使用“递增有序”条件,对本题时间性能不是最好。
用两个指针pa和pb分别指向a、b的结点,初始化指向首元素结点。通过一层循环,比较当前pa和pb指向结点的元素值大小,分为以下三中情况:
pa->data==pb->data,说明pa指示元素在b中,后移指针pa,有因是集合,可同时后移pb,即执行:pa=pa->next,pb=pb->next。
pa->data>pb->data,说明pa指示元素可能在b中pb指示的元素后面,pa不动,后移pb指针,即执行:pb=pb->next。
pa->datadata,说明pa指示元素不可能在b中,因b中后面的元素值越来越大。直接返回0,即a不是b的子集。
循环执行上述操作,直到其中一个表到达表尾。
结束循环后,要根据a、b中谁到达表尾作如下判断:
如果a表到达表尾,不管b表如何,说明a的所有元素都在b中,a是b的子集。返回1。为什么呢?
否则,b到达表尾,而a表中尚有元素,且不在b中,a不是b的子集,返回0。
算法描述】int subsetdecision( node* a, node* b )
node *pa, *pb;
pa=a->next; /pa和pb分别指向a和b表的首元素结点。
pb=b->next;
while(pa!=null &&pb!=null)
else if(pa->data>pb->data)
pb=pb->next; /pa指示元素可能在b中pb指示的元素后面,后移pb
elsereturn 0; /此时,pa->datadata,pa指示元素不可能在b中,a非b子集。
下面根据a、b的结束情况,判定a是否b的自己。
if(pa==null)
return 1; /a到表尾,不管b表如何,a全部元素在b中,是b的子集。
elsereturn 0; /b到表尾,a未到表尾,a后面元素不在b中,a非b的子集。
算法分析】时间复杂度o(|a|+|b|)。
2.20设计算法将两个递增有序的带头结点的单链表a、b合并为一个递增有序的带头结点的单链表,并要求算法的时间复杂度为两个表长之和的数量级。
解:算法如下。
void merge_linklist1(node* la,node *lb)
//合并后,以la为头结点指针,lb指示的头结点删除。
node*pa,*pb,*r; /pa和pb为la和lb当前结点指针。
r为已经部分的尾指针
pa=la->next;
pb=lb->next;
r=la;while(pa!=null &&pb!=null)
else//以下处理2表不等长情况,//其中一个链表已经结束,另一个表尚未结束,//元素值都不小于已经接入部分,直接接入即可。
if(pa!=null) /lb已结束,la未结束。
r->next=pa ;
else //la已结束,lb未结束。
r->next=pb ;
delete(lb); 删除 lb 头结点。
2.21设计算法将链表l就地逆置,即利用原表各结点的空间实现逆置。
解:算法如下。
void listreverse_l(node *l)
//单链表的就地逆置
node *p,*q; /p指向当前待逆置结点,q指向p的下一个结点。
p=l->next; /p指向第1个元素结点。
l->next=null;
while(p!=null)
q=p->next; /指向待逆置结点的下一个结点。
p->next=l->next; /p->next指向已经逆置部分的第一个元素结点。
l->next=p; /p成为第1个元素结点,到此结点p逆置完成。
p=q; /p 和q都指向未逆置部分的第一个结点。
2.22设计算法将两个递增有序的带头结点的单链表a、b合并为一个递减有序的带头结点的单链表,并要求算法的时间复杂度为两个表长之和的数量级。
解:算法如下。
node* listjoinandreverse_l(node *a, node *b)
node *pa,*pb,*p,*l;
pa、pb分别指向a和b待逆置的结点。
l=a; /以l为合并后的头结点指针,即a的头结点指针。
pa=a->next;
pb=b->next;
l->next=null;
while(pa!=null &&pb!=null)else
//以下处理a、b不等长情况。
while(pa!=null &&pb==null) /a未结束,b已经结束。
while(pa==null &&pb!=null) /a已结束,b未结束。
return(l);
CH2作业答案
8 答 从25岁到59岁,共35年。存款的本利和f 5000 f a,6 35 5000 111.435 557175 元 他在60岁 74岁 共15年 之间每年可以领到 每年领款额a 5000 f a,6 35 a p,6 15 5000 111.435 0.10296 57369.738 573...
资产评估ch2作业
作业1 被评估资产购建于2007年6月,帐面原值为100万元,会计折旧年限为8年,2011年6月30日进行评估,已知。1 2007年以来,设备类环比 指数分别为 2 被评估设备的月人工成本比同类设备超支3000元。3 评估前,该设备的利用率为60 该设备正常使用条件下尚可使用6年,预计未来设备的利用...
CH2答案 给学生
第2章作业参 一 判断题1.2.3.二 单项选择题。三 填空题1.lea bx,buf2.7230h3.除以164.ffa3h5.地址00130h00131h00132h00133h00134h00135h00136h 四 综合题1.答 1 源 立即寻址 2 源 立即寻址 3 源 寄存器寻址 4 源...