第二章线性表一、单项选择题1、在顺序表中查找第i个元素的时间效率最高的算法的时间的复杂度是A。A.O(1)B.O(n)C.O(log2n)D.O(n)2、最好的情况下,在顺序表中按值查找一个元素算法时间的复杂度是D。A.O(n)B.O(n)C.O(log2n)D.O(1)3、在查找顺序表各结点概率相等的情况下,顺序按值查找某个元素的算法的时间的复杂度是B。A.O(1)B.O(n)C.O(n)D.O(log2n)4、在带有头结点的单链中插入一个新结点时不可能修改A。A.头指针B.头结点指针域C.开始结点指针域D.其它结点指针域5、在带头结点的单链中删除由某个指针变量指向的结点的直接后继算法时间复杂度是B。A.O(n)B.O(1)C.O(n)D.O(log2n)6、在带头结点的单链中,若被删除结点位置概率相等,那么,删除第i个结点算法的时间复杂度是D。A.O(1)B.O(log2n)C.O(n)D.O(n)二、填空题1、顺序表的存储密度是1,而链式存储结构的存储密度值一定是1。2、头指针的值或为NULL,或为单链表第1个结点的地址。3、在顺序表中按值查找一个元素的时间耗费不仅与表长有关,还与被查找元素在顺序表中的位置有关。4、在不带头结点的单链表的结点类型为typedefstrutnode{intdata;structnode*next;}TNode;若sizeof(int)=2,sizeof(structnode*)=4,则该单链表的存储密度值为1/3。5、在单链表中查找第i个结点算法的时间复杂度是O(n)。三、基础知识1、试描述头指针、头结点、开始结点的区别,并说明头指针和头结点的作用。头指针是一个指针变量。若相应的链表有表头结点,则头指针指向该头结点;否则,头指针的值或者为NULL或者为开始结点的地址。头结点是在开始结点之前的一个附加的结点,它不存储线性表中的元素信息。它的引入,使得空表和非空表处理一致;还使得对链表在不同位置上的处理(插入、删除)一致。开始结点是存放线性表第一个元素值的结点,它没有直接前驱。2、何时选用顺序表、何时选用链表作为线性表的存储结构为宜?顺序表:若线性表大小事先知道,且插入、删除运算不多,而按序号查找运算较多时;链表:若线性表中元素事先不知道有多少,或者插入、删除运算很多时。3、在顺序表中插入和删除一个结点需平均移动多少个结点?具体的移动次数取决于哪两个因素?插入:n/2,插入位置、表中元素个数。删除:(n-1)/2,删除结点位置、表中元素个数。4、为什么在单循环链表中设置尾指针比设置头指针好?单循环链表的操作经常是对其开始结点和最后(终端)结点进行。用尾指针很容易表示开始结点(不带头结点:rear-next或带头结点:rear-next-next)和终端结点(rear)。5、在单链表、双链表、单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点*p从相应的链表中删去?若可以,其时间复杂度是多少?单链表:无法。双链表:可以;其时间复杂度是O(1)。单循环链表:可以;其时间复杂度是O(n)。6、下述算法的功能是什么?LinkListDemo(LinkListL){//L是无头结点的单链表ListNode*q,*p;if(L&&L-next){q=L;L=L-next;p=L;while(p-next)p=p-next;p-next=q;q-next=NULL;}returnL;}//Demo若L指向的单链表至少有两个结点,则L指向第2个结点,把第1个结点移到最后一个结点之后,返回L值;否则直接返回L值。四、算法设计题1、设顺序表va中的数据元素递增有序。试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。StatusInsert_SqList(SqList&va,intx)//把x插入递增有序表va中{if(va.length+1va.listsize)returnERROR;va.length++;for(i=va.length-1;va.elem[i]x&&i=0;i--)va.elem[i+1]=va.elem[i];va.elem[i+1]=x;returnOK;}//Insert_SqList2、试写一算法在带头结点的单链表结构上实现线性表操作LOCATE(L,X)。LNode*Locate(LinkListL,intx)//链表上的元素查找,返回指针{for(p=l-next;p&&p-data!=x;p=p-next);returnp;}//Locate3、试写一算法在带头结点的单链表结构上实现线性表操作LENGTH(L)。intLength(LinkListL)//求链表的长度{for(k=0,p=L;p-next;p=p-next,k++);returnk;}//Length4、试写一算法实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,a2,…,an)逆置为(an,an-1,…,a1)。voidreverse(SqList&A)//顺序表的就地逆置{for(i=0,j=A.length-1;ij;i++,j--)A.elem[i]-A.elem[j];}//reverse5、试写一算法,对单链表实现就地逆置。voidLinkList_reverse(Linklist&L)//链表的就地逆置;为简化算法,假设表长大于2{p=L-next;q=p-next;s=q-next;p-next=NULL;while(s-next){q-next=p;p=q;q=s;s=s-next;//把L的元素逐个插入新表表头}q-next=p;s-next=q;L-next=s;}//LinkList_reverse分析:本算法的思想是,逐个地把L的当前元素q插入新的链表头部,p为新表表头.6、设线性表A=(a1,a2,…,an),B=(b1,b2,…,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均未显式存储。voidmerge1(LinkList&A,LinkList&B,LinkList&C)//把链表A和B合并为C,A和B的元素间隔排列,且使用原存储空间{p=A-next;q=B-next;C=A;while(p&&q){s=p-next;p-next=q;//将B的元素插入if(s){t=q-next;q-next=s;//如A非空,将A的元素插入}p=s;q=t;}//while}//merge1