第二章 部分习题参考答案

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2 何时选用顺序表,何时选用链表作为线性表的存储结构合适? 各自的主要优缺点是什么?
在实际应用中,应根据具体问题的要求和性质来选择顺序表或链表作为线性表的存储结构,通常有以下几方面的考虑:
1.基于空间的考虑。

当要求存储的线性表长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表;反之,当线性表长度变化大,难以估计其存储规模时,采用动态链表作为存储结构为好。

2.基于时间的考虑。

若线性表的操作主要是进行查找,很少做插入和删除操作时,采用顺序表做存储结构为宜;反之,若需要对线性表进行频繁地插入或删除等的操作时,宜采用链表做存储结构。

并且,若链表的插入和删除主要发生在表的首尾两端,则采用尾指针表示的单循环链表为宜。

顺序表的主要优点: 没使用指针,不用花费附加开销 ;线性表元素的读写访问非常简洁便利
链表的主要优点:无需事先了解线性表的长度;能够适应经常插入删除内部元素的情况; 允许线性表的长度有很大变化
3 在顺序表中插入和删除一个结点平均需要移动多少个结点? 具体的移动次数取决于哪两个因素?
在等概率情况下,顺序表中插入一个结点需平均移动n/2个结点。

删除一个结点需平均移动(n-1)/2个结点。

具体的移动次数取决于顺序表的长度n以及需插入或删除的位置i。

i 越接近n则所需移动的结点数越少。

4 链表所表示的元素是否有序? 如有序,则有序性体现于何处? 链表所表示的元素是否一定要在物理上是相邻的? 顺序表的有序性又如何理解?
有序。

有序性体现在通过指针数据元素有序的相连。

物理上不一定要相邻。

顺序表的有序不仅体现在逻辑结构上有序,而且在物理结构(储存结构)也有序。

5 设顺序表L是递增有序表,试写一算法,将x插入到L中并使L仍是递增有序表。

因已知顺序表L是递增有序表,所以只要从顺序表终端结点(设为i位置元素)开始向前寻找到第一个小于或等于x的元素位置i后插入该位置即可。

在寻找过程中,由于大于x的元素都应放在x之后,所以可边寻找,边后移元素,当找到第一个小于或等于x的元素位置i时,该位置也空出来了。

算法如下:
void InsertIncreaseList( Seqlist *L , Datatype x )
{
inti;
if ( L->length>=ListSize)
Error(“overflow");
for ( i=L -> length ; i>0 && L->data[ i-1 ] > x ; i--)
L->data[ i ]=L->data[ i ] ; // 比较并移动元素
L->data[ i ] =x;
L -> length++;
}
6 写一求单链表的结点数目ListLength(L)的算法。

由于在单链表中只给出一个头指针,所以只能用遍历的方法来数单链表中的结点个数了。

算法如下:
intListLength ( LinkList L )
{
intlen=0 ;
ListNode *p;
p=L; //设该表有头结点
while ( p->next )
{
p=p->next;
len++;
}
return len;
}
7 写一算法将单链表中值重复的结点删除,使所得的结果链表中所有结点的值均不相同。

本题可以这样考虑,先取开始结点中的值,将它与其后的所有结点值一一比较,发现相同的就删除掉,然后再取第二结点的值,重复上述过程直到最后一个结点。

具体算法:
void DeleteList ( LinkList L )
{
ListNode *p , *q , *s;
p=L-next;
while( p->next&&p->next->next)
{
q=p;//由于要做删除操作,所以q指针指向要删除元素的直接前趋
while (q->next)
if (p->data==q->next->data)
{s=q->next;q->next=s->next;free(s);//删除与*p的值相同的结点
}
else q=q->next;
p=p->next;
}
}
8 写一算法从一给定的向量A删除值在x到y(x≤y)之间的所有元素(注意:x和y是给定的参数,可以和表中的元素相同,也可以不同)。

voidDeletElem(SqListA,intx,int y)
{
ElemType *p,*q;
inti=0; int j;
p=&A.next;
for(i;i<A.length;i++)
{ if(p.data>=x||p.data<=y)
{ q=p; (p-1).next=p.next; }
p++; free(q);
}
}
9 设A和B是两个按元素值递增有序的单链表,写一算法将A和B归并为按元素值递减有序的单链表C,试分析算法的时间复杂度。

根据已知条件,A和B是两个递增有序表,所以可以先取A表的表头建立空的C表。

然后同时扫描A表和B表,将两表中最大的结点从对应表中摘下,并作为开始结点插入C表中。

如此反复,直到A表或B表为空。

最后将不为空的A表或B表中的结点依次摘下并作为开始结点插入C表中。

这时,得到的C表就是由A表和B表归并成的一个按元素值递减有序的单链表C。

算法如下:
LinkListMergeSort ( LinkList A , LinkList B )
{// 归并两个带头结点的递增有序表为一个带头结点递减有序表
ListNode *pa , *pb , *q , *C ;
pa=A->next;//pa指向A表开始结点
C=A;C->next=NULL;//取A表的表头建立空的C表
pb=B->next;//pb指向B表开始结点
free(B);//回收B表的头结点空间
while ( pa &&pb)
{
if ( pb->data <= pa->data )
{ // 当B中的元素小于等于A中当前元素时,将pa表的开始结点摘下
q=pa;pa=pa->next;
}
else
{// 当B中的元素大于A中当前元素时,将pb表的开始结点摘下
q=pb;pb=pb->next;}
q->next=C->next;C->next=q;//将摘下的结点q作为开始结点插入C表}
//若pa表非空,则处理pa表
while(pa){
q=pa;pa=pa->next;
q->next=C->next;C->next=q;}
//若pb表非空,则处理pb表
while(pb){
q=pb;pa=pb->next;
q->next=C->next;C->next=q;}
return(C);
}
该算法的时间复杂度分析如下:
算法中有三个while 循环,其中第二个和第三个循环只执行一个。

每个循环做的工作都是对链表中结点扫描处理。

整个算法完成后,A表和B表中的每个结点都被处理了一遍,则该算法的时间复杂度为
O(ListLength (A)+ListLength (B) )。

相关文档
最新文档