算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx

上传人:b****3 文档编号:17010640 上传时间:2022-11-27 格式:DOCX 页数:13 大小:27.67KB
下载 相关 举报
算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx_第1页
第1页 / 共13页
算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx_第2页
第2页 / 共13页
算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx_第3页
第3页 / 共13页
算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx_第4页
第4页 / 共13页
算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx

《算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx》由会员分享,可在线阅读,更多相关《算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx(13页珍藏版)》请在冰豆网上搜索。

算法与数据结构C语言版课后习题答案机械工业出版社第1章绪论习题参考答案Word文档格式.docx

{k=k+50*i;

i++;

 @     {if(i〉j)j++;

 @

   }         elsei++;

} @

 (3)x=y=0;

      (4)x=91;

y=100;

   for(i=0;

i〈n;

i++)  while(y〉0)

  for(j=0;

j<

n;

j++) @    if(x>

100)

  {x++;

  @   {x=x—10;

y——;

     

 for(k=0;

k〈n;

k++)@    }

 y++;

  @      elsex++;

   @

   }          

【解答】

(1)n—1

(2)n为偶数时,均为ndiv2;

您为奇数时,分别为:

(ndiv2)+1与ndiv2

(3)n+1, n(n+1),n2,(n+1)n2,n3 

(4)100,1000

4.有实现同一功能得两个算法A1与A2,其中A1得时间复杂度为Tl=O(2n),A2得时间复杂度为T2=O(n2),仅就时间复杂度而言,请具体分析这两个算法哪一个好?

【解答】对算法A1与A2得时间复杂度T1与T2取对数,得nlog2与2logn。

显然,当n<

4时,算法A1好于A2;

当n=4时,两个算法时间复杂度相同;

当n〉4时,算法A2好于A1、

7、 选择题:

算法分析得目得就是()

A、找出数据结构得合理性  B、研究算法中得输入与输出得关系

C、分析算法得效率以求改进D、分析算法得易懂性与文档特点

【解答】C

二、算法设计题

8、 已知输入x,y,z三个不相等得整数,设计一个“高效”算法,使得这三个数按从小到大输出。

“高效"

得含义就是用最少得元素比较次数、元素移动次数与输出次数。

voidBest()

{ //按序输出三个整数得优化算法

inta,b,c,t;

scanf(“%d%d%d"

&

a,&b,&c);

if(a>b)

{t=a;

a=b;

b=t:

} //a与b已正序

if(b〉c)

{t=c;

c=b;

     //c已到位

if(a>

t) {b=a;

a=t;

} //a与b已正序

elseb=t;

}//if

printf(“%d,%d,%d\n”,a,b,c);

//最佳2次比较,无移动;

最差3次比较,7个赋值

}

6.在数组A[n]中查找值为k得元素,若找到则输出其位置i(1≤i≤n),否则输出0作为标志。

设计算法求解此问题,并分析在最坏情况下得时间复杂度

【题目分析】从后向前查找,若找到与k值相同得元素则返回其位置,否则返回0。

intSearch(ElemType A[n+1], ElemTypek)

{i=n;

wile(i〉=1)&

&(A[i]!

=k))i-—;

if(i>=1)returni;

elsereturn 0;

当查找不成功时,总得比较次数为n+1次,所以最坏情况下时间复杂度为O(n)。

第2章线性表习题参考答案

2.1 试述头指针、头结点、元素结点、首元结点得区别,说明头指针与头结点得作

【解答】指向链表第一个结点(或为头结点或为首元结点)得指针称为头指针、“头指针”具有标识一个链表得作用,所以经常用头指针代表链表得名字,如链表L既就是指链表得名字就是L,也就是指链表得第一个结点得地址存储在指针变量L中,头指针为“NULL”则表示一个空表。

有时,我们在整个线性链表得第一个元素结点之前加入一个结点,称为头结点,它得数据域可以不存储任何信息(也可以做监视哨或存放线性表得长度等附加信息),指针域中存放得就是第一个数据结点得地址,空表时为空、 “头结点”得加入,使插入与删除等操作方便统一。

元素结点即就是数据结点,至少包括元素自身信息与其后继元素得地址两个域。

首元结点就是指链表中第一个数据元素得结点;

为了操作方便,通常在链表得首元结点之前附设一个结点,称为头结点。

2.2分析顺序存储结构与链式存储结构得优缺点,说明何时应该利用何种结构、

【解答】①从空间上来瞧,当线性表得长度变化较大,难以估计其规模时,选用动态得链表作为存储结构比较合适,但链表除了需要设置数据域外,还要额外设置指针域,因此当线性表长度变化不大,易于事先确定规模时,为了节约存储空间,宜采用顺序存储结构、

②从时间上瞧,顺序表具有按元素序号随机访问得特点,在顺序表中按序号访问数据元素得时间复杂度为O

(1);

而链表中按序号访问得时间复杂度为O(n)。

所以如果经常按序号访问数据元素,使用顺序表优于链表、

在顺序表中做插入删除操作时,平均移动大约表中一半得元素,因此n较大时顺序表得插入与删除效率低、在链表中作插入、删除,虽然也要找插入位置,但操作主要就是比较操作、从这个角度考虑显然链表优于顺序表、

总之,两种存储结构各有长短,选择那一种存储结构,由实际问题中得主要因素决定、

3分析在顺序存储结构下插入与删除结点时平均需要移动多少个结点。

【解答】平均移动表中大约一半得结点,插入操作平均移动个结点,删除操作平均移动个结点、具体移动得次数取决于表长与插入、删除得结点得位置。

4 为什么在单循环链表中常使用尾指针,若只设头指针,插入元素得时间复杂度如何?

【解答】单循环链表中无论设置尾指针还就是头指针都可以遍历表中任一个结点。

设置尾指针时,若在表尾进行插入元素或删除第一元素,操作可在O

(1)时间内完成;

若只设置头指针,表尾进行插入或删除操作,需要遍历整个链表,时间复杂度为O(n)。

2、5在单链表、双链表、单循环链表中,若知道指针p指向某结点,能否删除该结点,时间复杂度如何?

【解答:

】以上三种链表中,若知道指针p指向某结点,都能删除该结点。

双链表删除p所指向得结点得时间复杂度为O

(1),而单链表与单循环链表上删除p所指向得结点得时间复杂度均为O(n)。

2、6 下面算法得功能就是什么?

LinkedListUnknown(LinkedListla)

{LNode*q,*p;

 if(la&

&

la->

next)

 {q=la;

la=la-〉next;

p=la;

  while(p->

next)p=p-〉next;

  p—〉next=q;

q—>next=null;

   }

    returnla;

  }

【解答】将首元结点删除并插入到表尾(设链表长度大于1)。

2.7选择题:

在循环双链表得*p结点之后插入*s结点得操作就是( )

la、p-〉next=s;

 s->

prior=p;

p->

next—〉prior=s;

s->next=p->next;

B、p-〉next=s;

 p-〉next-〉prior=s;

prior=p;

 s—〉next=p->

next;

lc、s->prior=p;

s->

next=p->

next;

p—>

next:

=s;

   p-〉next->prior=s;

D、s->prior=p;

s>next=p〉next;

 p>

next->

prior=s;

 p—〉next=s;

【解答】D

2.8选择题:

若某线性表最常用得操作就是存取任一指定序号得元素与在最后进行插入与删除运算,则利用()存储方式最节省时间。

la。

顺序表 B.双链表 lc.带头结点得双循环链表 D、单循环链表

【解答】la

9 设ha与hb分别就是两个带头结点得非递减有序单链表得头指针,试设计算法,将这两个有序链表合并成一个非递增有序得单链表、要求使用原链表空间,表中无重复数据。

【题目分析】因为两链表已按元素值非递减次序排列,将其合并时,均从第一个结点起进行比较,将小得链入链表中,同时后移链表工作指针,若遇值相同得元素,则删除之、该问题要求结果链表按元素值非递增次序排列,故在合并得同时,将链表结点逆置。

LinkedList Union(LinkedListha,hb)

 ∥ha,hb分别就是带头结点得两个单链表得头指针,链表中得元素值按递增序排列

∥本算法将两链表合并成一个按元素值递减次序排列得单链表,并删除重复元素

  {pa=ha—>

next;

∥pa就是链表ha得工作指针

pb=hb—>next;

 ∥pb就是链表hb得工作指针

ha->next=null;

∥ha作结果链表得头指针,先将结果链表初始化为空

  while(pa!

=null&

& pb!

=null)∥当两链表均不为空时作

  {while(pa-〉next &

&pa—>

data==pa->

next->

data)

 {u=pa—>

pa—〉next=u—>

next;

free(u)}∥删除pa链表中得重复元素

while(pb->next&

 pb->

data==pb-〉next->data)

   {u=pb—>

pb—>

next=u-〉next;

free(u)}∥删除pb链表中得重复元素

  if(pa->data〈pb—>data)

   {r=pa->next;

   ∥将pa得后继结点暂存于r

   pa->next=ha->next;

  ∥将pa结点链于结果表中,同时逆置

ha-〉next=pa;

pa=r;

   ∥恢复pa为当前待比较结点

  elseif(pb—>data〈pa-〉data)

{r=pb-〉next;

   ∥将pb 得后继结点暂存于r

pb-〉next=ha-〉next;

∥将pb结点链于结果表中,同时逆置

ha—>

next=pb;

pb=r;

    ∥恢复pb为当前待比较结点

   else{u=pb;

pb=pb->next;

free(u)}∥删除链表pb与pa中得重复元素

  }//while(pa!

=null&&

 pb!

=null)

   if(pa) pb=pa;

 ∥避免再对pa写下面得while语句

   while(pb!

=null) ∥将尚未到尾得表逆置到结果表中

   {r=pb-〉next;

pb->next=ha-〉next;

ha—〉next=pb;

pb=r;

   returnha

 }∥算法Union结束

2、11 

 设p指向头指针为la得单链表中某结点,试编写算法,删除结点*p得直接前驱结点、

【题目分析】设*p就是单链表中某结点,删除结点*p得直接前驱结点,要找到*p得前驱结点得前驱*pre、进行如下操作:

u=pre—>

next;

pre—>next=u—〉next;

free(u);

LinkedList LinkedListDel(LinkedListla,LNode*p)

{∥删除单链表la上得结点*p得直接前驱结点,假定*p存在

pre=la;

if(pre-next==p)

printf(“*p就是链表第一结点,无前驱\n”) 

;

exit(0) 

 }

ﻩwhile(pre—>

next-〉next!

=p)

   pre=pre->next;

u=pre—>next;

pre->

next=u-〉next;

free(u);

return(la);

2、12设计一算法,将一个用循环链表表示得稀疏多项式分解成两个多项式,使这两个多项式各自仅有奇次幂或偶次幂项,并要求利用原链表中得结点空间来构造这两个链表。

【题目分析】设循环链表表示得多项式得结点结构为:

   typedefstruct node

 {int power;

  ∥幂

floatcoef;

  ∥系数

     ElemType other;

  ∥其她信息

 structnode*next;

∥指向后继得指针

}PNode,*PolyLinkedList;

则可以从第一个结点开始,根据结点得幂就是奇数或偶数而将其插入到奇次幂或偶次幂项得链表中、假定用原链表保存偶次幂,要为奇次幂得链表生成一个表头,为了保持链表中结点得原来顺序,用一个指针指向奇次幂链表得表尾,注意链表分解时不能“断链”。

voidPolyDis(PolyLinkedListpoly)

∥将poly表示得多项式链表分解为各含奇次幂或偶次幂项得两个循环链表

{PolyLinkedListpoly2=(PolyLinkedList)malloc(sizeof(PNode));

       ∥poly2表示只含奇次幂得多项式

r2=poly2;

∥r2就是只含奇次幂得多项式链表得尾指针

r1=poly;

   ∥r1就是只含偶次幂得多项式链表当前结点得前驱结点得指针

p=poly->

∥链表带头结点,p指向第一个元素

while(p!

=poly)

  if(p—>

power%2)∥处理奇次幂

  {r=p-〉next;

∥暂存后继

    r2—〉next=p;

∥结点链入奇次幂链表

r2=p;

  ∥尾指针后移

 p=r;

 ∥恢复当前待处理结点

 }

  else∥处理偶次幂

 {r1—>next=p;

 r1=p;

p=p->next;

 }

r->

next=poly2;

r1—〉next=poly;

∥构成循环链表

}∥PolyDis

2、14 

设单向链表得头指针为head,试设计算法,将链表按递增得顺序就地排序、

【题目分析】本题中得“就地排序”,可理解为不另辟空间,这里利用直接插入原则把链表整理成递增有序链表。

LinkedList LinkListInsertSort(LinkedListhead)

∥head就是带头结点得单链表,本算法利用直接插入原则将链表整理成递增得有序链表

{if(head—〉next!

=null)  ∥链表不为空表

 {p=head->next—〉next;

 ∥p指向第一结点得后继

head->

next->

next=null;

∥直接插入原则认为第一元素有序,然后从第二元素起依次插入

while(p!

=null)

 {r=p->next;

     ∥暂存p得后继

 q=head;

 while(q->

next&

& q->next-〉data<p-〉data)

q=q->

∥查找插入位置

p->next=q—>

next;

  ∥将p结点链入链表

q->

next=p;

p=r;

} }

2.15 

已知递增有序得三个单链表分别代表集合A,B与C,设计算法实现A=A∪(B∩C),并使结果链表仍保持递增。

要求算法得时间复杂度为O(|A|+|B|+|C|)、其中,|A|为集合A得元素个数、

【题目分析】本题首先求B与C得交集,即求B与C中共有元素,再与A求并集,同时删除重复元素,以保持结果A递增。

LinkedListunion(LinkedListA,B,C)

∥A、B与C均就是带头结点得递增有序得单链表,本算法实现A=A∪(B∩C)

∥使结果表A保持递增有序

{pa=A->next;

pb=B->next;

pc=C->

next;

∥设置三个工作指针

pre=A;

∥pre指向结果链表中当前待合并结点得前驱

 A—>data=MaxElemType;

∥同类型元素最大值,起监视哨作用

while(pa|| pb&&pc)

 {while(pb&

&pc)

 if(pb->data<

pc—>data) pb=pb-〉next;

  elseif(pb->

data>

pc-〉data)pc=pc-〉next;

  else break;

∥B表与C表有公共元素

 if(pb &&

pc)

 {while(pa&

&pa—〉data<

pb—〉data)∥先将A中小于B,C公共元素部分链入

     {pre->

next=pa;

pre=pa;

pa=pa->

   if(pre—>

data!

=pb->

data)

{pre-〉next=pb;

pre=pb;

pb=pb-〉next;

pc=pc—>next;

  else{pb=pb->

pc=pc->next;

∥若A中已有B,C公共元素,则不再存入结果表

 }∥while(pa||pb&&

pc)

if(pa) pre->

next=pa;

elsepre->

next=null;

  ∥当B,C无公共元素,将A中剩余链入

}∥算法Union结束

16顺序表la与lb非递减有序,顺序表空间足够大。

试设计一种高效算法,将lb中元素合到la中,使新得la得元素仍保持非递减有序。

高效指最大限度地避免移动元素。

【题目分析】顺序存储结构得线性表得插入,其时间复杂度为O(n),平均移动近一半得元素。

线性表la与lb合并时,若从第一个元素开始,一定会造成元素后移,这不符合本题“高效算法”得要求、应从线性表得最后一个元素开始比较,大者放到最终位置上。

设两线性表得长度各为m与n,则结果表得最后一个元素应在m+n位置上、这样从后向前,直到第一个元素为止。

SeqListUnion(SeqListla,SeqListlb)

∥la与lb就是顺序存储得非递减有序线性表,本算法将lb合并到la中,元素仍非递减有序

{ m=la、last;

n=lb、last;

∥m,n分别为线性表la与lb得长度

  k=m+n—1;

∥k为结果线性表得工作指针(下标)

 i=m-1;

j=n—1;

 ∥i,j分别为线性表la与lb得工作指针(下标)

    while(i>=0&

 j〉=0)

  if(la、data[i]>

=lb。

data[j])la。

data[k—-]=la。

data[i——];

    elsela、data[k—-]=lb、data[j--];

    while(j>=0)la。

data[k--]=lb.data[j——];

   la、last=m+n;

return la;

【算法讨论】算法中数据移动就是主要操作。

在最佳情况下(lb得最小元素大于la得最大元素),仅将lb得n个元素移(拷贝)到la中,时间复杂度为O(n),最差情况,la得所有元素都要移动,时间复杂度为O(m+n)、因数据合并到la中,所以在退出第一个while循环后,只需要一个while循环,处理lb中剩余元素。

第二个循环只有在lb有剩余元素时才执行,而在la有剩余元素时不执行。

本算法“最大限度得避免移动元素”,就是“一种高效算法”。

2、17已知非空线性链表由head指出,试写一算法,将链表中数据域值最小得那个结点移到链表得最前面。

要求:

不得额外申请新得链结点。

【题目分析】本题要求将链表中数据域值最小得结点移到链表得最前面。

首先要查找最小值结点、将其移到链表最前面,实质上就是将该结点从链表上摘下(不就是删除并回收空间),再插入到链表得最前面。

LinkedList Delinsert(LinkedList head)

∥本算法将非空线性链表head中数据域值最小得那个结点移到链表得最前面

{p=head->

∥p就是链表得工作指针

pre=head;

 ∥pre指向链表中数据域最小值结点得前驱

q=p;

 ∥q指向数据域最小值结点,初始假定就是第一结点

while(p-〉next)

 {if(p->next-〉data<

q—>data){pre=p;

q=p->next;

}∥找到新得最小值结点

p=p->

if(q!

=head-〉next)∥若最小值就是第一元素结点,则不需再操作

{pre->next=q->

next;

 ∥将最小值结点从链表上摘下

q-〉next=head->

 ∥将q结点插到链表最前面

head—>

next=q;

}∥Delinsert

2.19 

三个带头结点得线性链表la、lb与lc中得结点均依元素值自小至大非递减排列(可能存在两个以上值相同得结点),编写算法对la表进行如下操作:

使操作后得la中仅留下三个表中均包含得数据元素得结点,且没有值相

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1