习题3链表教学文稿.docx
《习题3链表教学文稿.docx》由会员分享,可在线阅读,更多相关《习题3链表教学文稿.docx(11页珍藏版)》请在冰豆网上搜索。
习题3链表教学文稿
习题3(链表)
习题3(链表)
一、选择题
(1)链接存储的存储结构所占存储空间(A)。
A)分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针
B)只有一部分,存放结点值C)只有一部分,存储表示结点间关系的指针
D)分两部分,一部分存放结点值,另一部分存放结点所占单元数
(2)线性表若采用链式存储结构时,要求内存中可用存储单元的地址(D)。
A)必须是连续的B)部分地址必须是连续的C)一定是不连续的D)连续或不连续都可以
(3)线性表L在(B)情况下适用于使用链式结构实现。
A)需经常修改结点值B)需不断删除插入C)含有大量的结点D)结点结构复杂
(4)单链表的存储密度(C)。
A)大于1B)等于1C)小于1D)不能确定
(5)若指定有n个元素的向量,则建立一个有序单链表的时间复杂性的量级是(C)。
A)O
(1)B)O(n)C)O(n2)D)O(nlog2n)
(6)在单链表中,要将s所指结点插入到p所指结点之后,其语句应为(D)。
A)s->next=p+1;p->next=s;B)(*p).next=s;(*s).next=(*p).next;
C)s->next=p->next;p->next=s->next;D)s->next=p->next;p->next=s;
(7)在双向链表存储结构中,删除p所指的结点时须修改指针(A)。
A)p->next->prior=p->prior;p->prior->next=p->next;
B)p->next=p->next->next;p->next->prior=p;
C)p->prior->next=p;p->prior=p->prior->prior;
D)p->prior=p->next->next;p->next=p->prior->prior;
(8)在双向循环链表中,在p指针所指的结点后插入q所指向的新结点,其修改指针的操作是(C)。
A)p->next=q;q->prior=p;p->next->prior=q;q->next=q;
B)p->next=q;p->next->prior=q;q->prior=p;q->next=p->next;
C)q->prior=p;q->next=p->next;p->next->prior=q;p->next=q;
D)q->prior=p;q->next=p->next;p->next=q;p->next->prior=q;
(9)链表可以带表头结点,也可以不带表头结点,前者最主要的好处是(B)。
A)加快表的遍历B)使空表和非空表的处理统一C)节省存储空间D)提高存取元素的速度
(10)在单链表指针p所指向的结点后面插入一个新结点q的操作语句序列为(A)。
A)q->next=p->next;p->next=q;B)p=p->next;p->next=q->next;
C)q=p->next;q->next=p->next;D)p->next=q;q->next=p->next;
(11)在一个单链表中,若要删除p个结点的后继结点,则执行(A)
A)p->next=p->next->next;B)p=p->next;p->next->next;
C)free(p->next);D)p=p->next->next;
(12)设rear是指向非空带头结点的循环单链表的尾指针,则删除表首结点的操作可表示为(B)
A)p=rear;B)p=rear->next->next;
Rear=rear->next;rear->next->next=p->next;
free(p);free(p);
C)rear:
=rear->next->next;D)rear=rear->next
free(rear);free(rear);
(13)循环链表主要优点是(D)
A)不再需要头指针了
B)已知某个结点的位置后,能够容易找到它的直接前趋
C)在进行插入,删除运算时,能更好地保证链表断开
D)从表中任一结点出发都能扫描到整个链表
(14)用链表表示线性表的优点是(C)
A)便于随机存取B)花费的存储空间较顺序存储少
C)便于插入和删除操作D)数据元素的物理顺序和逻辑顺序相同
(15)最常用操作是在最后一个元素之后插入一个元素和删除最后一个元素,则用(B)存储方式最佳。
A)单链表B)双链表C)单循环链表D)带头结点的双循环链表
(16)指针p1和p2分别指向两个无头结点的非空单循环链表中的尾结点,要将两个链表链接成一个新的单循环链表,应执行的操作为(D)
A)p1->next=p2->next;p2->next=p1->next;B)p2->next=p1->next;p1->next=p2->next;
C)p=p2->next;p1->next=p;p2->next=p1->next;
D)p=p1->next;p1->next=p2->next;p2->next=p;
二、填空题
(1)在单向链表某P结点之后插入S结点的操作是(s->next=p->next;p->next=s;)。
(2)对于一个具有n个结点的单链表,在已知的结点*p后插入一个新结点的时间复杂度为(O
(1)),在给定值为x的结点后插入一个新结点的时间复杂度为(O(n))。
(3)设长度为n的链队列用只设尾指针的单循环链表表示,则出队操作的时间复杂度为(O
(1)),若用只设头指针的单循环链表表示,则出队操作的时间复杂度为(O
(1))。
(4)在双向链表中,每个结点有两个指针域,一个指向(直接后继),另一个指向(直接前驱)。
(5)在一个单链表中的p所指结点之后插入一个s所指结点时,执行的操作为(
s->next=p->next;p->next=s;)。
(6)在一个单链表中的p所指结点之前插入一个s所指结点时,执行的操作为(s->next=p;p=s;)。
(7)在一个单链表中删除p所指结点时,应执行的操作是(q=p;p=p->next;free(q))。
(8)对于双向链表,在两个结点之间插入一个新结点需修改的指针共(4)个。
(9)带有一个头结点的单链表Head为空的条件是(Head->next=Null)。
(10)非空循环单链表head的尾结点(由p所指向),满足条件(p->next=head)。
(11)对于一个具有n个结点的单链表,在已知p所指结点后插入一个新结点的时间复杂度为(O
(1));在给定值为x的结点后插入一个新结点的时间复杂度为(O(n))。
(12)循环链表中最后一个结点的(指针域)指向头结点,整个链表形成一个(环)。
(13)在单链表中,每个结点有(一个)指针域,最后一个结点的指针域为(空)。
(14)已知链表结点定义如下,每个字符占1个字节,指针占4个字节,则该链表的存储密度是(80%)。
typedefstructnode{chardata[16];structnode*next;}LinkStrNode;
(15)下面是对不带头结点的单链表进行就地逆置的算法,该算法用L返回逆置后的链表的头指针。
voidreverse(linklist&L)
{p=null;q=L;
while(q!
=null){(L=q->next);q->next=p;p=q;(q=L);}
(L=p);
}
三、算法设计题
(4)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。
Linklistf4(LinklistA)
{
if(A->next=NULL)
returnNULL;
p=A->next;q=p->next;
while(q)
{
if(q->data>p->data)
p=q;
q=p->next;
}
returnp;
}
(5)设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间
Voidinverse(LinkList &L)
{
// 逆置带头结点的单链表 L
p=L->next; L->next=NULL;
while ( p)
{
q=p->next; // q指向*p的后继
p->next=L->next;
L->next=p; // *p插入在头结点之后
p = q;
}
}
(6)设计一个算法,删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同)。
void delete(LinkList &L, int mink, int maxk)
{ p=L->next; //首元结点
while (p && p->data<=mink)
{ pre=p; p=p->next; } //查找第一个值>mink的结点
if (p) {
while (p && p->datap=p->next;//查找第一个值≥maxk 的结点
q=pre->next;
pre->next=p; // 修改指针
while (q!
=p)
{ s=q->next; delete q; q=s; } // 释放结点空间
}//if
}
(7)设计算法计算不带头结点的单链表长度。
intf7(LinklistA)
{intc=0;P=A;
While(P)
{c++;p=p->next;}
returnc;
}
(9)有一单链表,其结点的元素值以非递减有序排列。
试编写删除该单链表中多余的元素值相同的结点的算法。
Voidf9(LinklistA)
{p=A->next;
While(p&&p->next)
{if(p->data==p->next->data)
{
q=p->next;p->next=q->next;free(q);
}
else
p=p->next;
}
}
(10)设键盘输入n个英语单词,输入格式为n,w1,w2,…,wn,其中n表示随后输入英语单词个数,试编一程序,建立一个单向链表。
如果单词重复出现,则只在链表上保留一个。
链表结点还应有一个计数域,记录该单词重复出现的次数,然后输出出现次数最多的前k(k<=n)个单词。
(1)LinkList creat(){
// 建立有n(n>0)个单词的单向链表,若单词重复出现,则只在链表中保留一个
LinkList la; //申请头节点
la=(LinkList)malloc(sizeof(node)); // 链表初始化
la->next=null; // 建立n个节点的链表
for(i=1;i<=n;i++){ // a是与链表中节点数据域同等长度的字符数组
scanf(“%s”,a); // p是工作指针,pre是前驱指针
p=la->next; pre=p;
While(p!
=null)
If(strcmp(p->data,a)==0){
p->freq++; //单词重复出现,频度增1
Break; } else{ pre=p;
p=p->next; // 指针后移 }
if(p==null){ // 该单词没出现过,应插入
p=(LinkList)malloc(sizeof(node)); strcopy(p->data,a); p->freq=1;
p->next=null; // 将新节点插入到链表最后
pre->next=p;
}
} // 结束for循环 return la;
} // 算法结束
(2) Void CreatOut(){
/* 建立有n个单链表的单项链表,重复单词只在链表中保留一个,最后输出频度最高的k个单词 */
LinkList la; //申请头节点
la=(LinkList)malloc(sizeof(node)); //链表初始化
la->next=null; //建立n个节点的链表
for(i=1;i<=n;i++){ //a是与链表中节点数据域同等长度的字符数组 scanf(“%s”,a); //p是工作指针,pre是指针前驱 p=la->next; pre=p;
while(p!
=null)
if(strcmp(p->data,a)==0){
p->freq++; //单词重复出现,频度增1 pre->next=p->next; //先将节点p从链表上摘下,再按频度域值插入到合适位置
pre=la; q=la->next;
while(q->freq>p->freq){ pre=q; q=q->next; }
pre->next=p;
p->next=q; //将p结点插入到合适位置
} else{ pre=p;
p=p->next; // 指针后移
}
if(p==null){ //该单词没出现过,应插入到链表最后
p=(LinkList)malloc(sizeof(node)); strcopy(p->data,a); p->freq=1; p->next=null; pre->next=p;
} //新结点插入
} //结束for循环建表
int k,i=0;
scanf(“输入要输出的单词的个数%d”,&k); p=la->next;
while(p&&i printf( “第%d个单词%s出现%d次\n”,++I,p->freq); p=p->next; }
if(!
p) printf(“给出的%d值太大\n”,k);
//算法结束
(13)设有一头指针为L的带有表头结点的非循环双向链表,其每个结点中除有pred(前驱指针),data(数据)和next(后继指针)域外,还有一个访问频度域freq。
在链表被起用前,其值均初始化为零。
每当在链表中进行一次Locate(L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点的最后,以便使频繁访问的结点总是靠近表头。
试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。
LinkList locate(LinkList L,ElemType x) ∥ L是带头结点的按访问频度递减的双向链表,本算法先查找数据x,查找成功时结点的访问频度域增1,最后将该结点按频度递减插入链表中适当位置。
{ LinkList p=L->next,q;
∥p为工作指针,q为p的前驱,用于查找插入位置。
while (p && p->data !
=x)
p=p->next; ∥ 查找值为x的结点。
if (!
p)
{ printf(“不存在值为x的结点\n”);
exit(0); } else
{
p->freq++; ∥令元素值为x的结点的freq域加1 。
p->next->pred=p->pred; ∥ 将p结点从链表上摘下。
p->pred->next=p->next;
q=p->pred; ∥ 以下查找p结点的插入位置
while (q !
=L && q->freqfreq)
q=q->pred;
p->next=q->next; q->next->pred=p;∥将p结点插入 p->pred=q; q->next=p; }
return(p); ∥返回值为x的结点的指针}}