数据结构第3章+特殊线表习题解析(答)
- 格式:doc
- 大小:32.04 KB
- 文档页数:3
第三章习题1.按图3.1(b)所示铁道(两侧铁道均为单向行驶道)进行车厢调度,回答:⑴如进站的车厢序列为123,则可能得到的出站车厢序列是什么?⑵如进站的车厢序列为123456,能否得到435612和135426的出站序列,并说明原因。
(即写出以“S”表示进栈、以“X”表示出栈的栈操作序列)。
2.设队列中有A、B、C、D、E这5个元素,其中队首元素为A。
如果对这个队列重复执行下列4步操作:(1)输出队首元素;(2)把队首元素值插入到队尾;(3)删除队首元素;(4)再次删除队首元素。
直到队列成为空队列为止,得到输出序列:(1)A、C、E、C、C (2) A、C、E(3) A、C、E、C、C、C (4) A、C、E、C3.给出栈的两种存储结构形式名称,在这两种栈的存储结构中如何判别栈空与栈满?4.按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,画出对下列算术表达式求值时操作数栈和运算符栈的变化过程:A-B*C/D+E↑F5.试写一个算法,判断依次读入的一个以@为结束符的字母序列,是否为形如‘序列1& 序列2’模式的字符序列。
其中序列1和序列2中都不含字符’&’,且序列2是序列1的逆序列。
例如,‘a+b&b+a’是属该模式的字符序列,而‘1+3&3-1’则不是。
6.假设表达式由单字母变量和双目四则运算算符构成。
试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰式。
7.假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。
8.要求循环队列不损失一个空间全部都能得到利用, 设置一个标志域tag , 以tag为0或1来区分头尾指针相同时的队列状态的空与满,请编写与此结构相应的入队与出队算法。
9.简述以下算法的功能(其中栈和队列的元素类型均为int):(1)void proc_1(Stack S){ int i, n, A[255];n=0;while(!EmptyStack(S)){n++; Pop(&S, &A[n]);}for(i=1; i<=n; i++)Push(&S, A[i]);}(2)void proc_2(Stack S, int e) { Stack T; int d;InitStack(&T);while(!EmptyStack(S)){ Pop(&S, &d);if (d!=e) Push( &T, d);}while(!EmptyStack(T)){ Pop(&T, &d);Push( &S, d);}}(3)void proc_3(Queue *Q){ Stack S; int d;InitStack(&S);while(!EmptyQueue(*Q)){DeleteQueue(Q, &d);Push( &S, d);}while(!EmptyStack(S)){ Pop(&S, &d);EnterQueue(Q,d)}}实习题1.回文判断。
第三章习题1.按图3.1(b)所示铁道(两侧铁道均为单向行驶道)进行车厢调度,回答:⑴如进站的车厢序列为123,则可能得到的出站车厢序列是什么?⑵如进站的车厢序列为123456,能否得到435612和135426的出站序列,并说明原因。
(即写出以“S”表示进栈、以“X”表示出栈的栈操作序列)。
2.设队列中有A、B、C、D、E这5个元素,其中队首元素为A。
如果对这个队列重复执行下列4步操作:(1)输出队首元素;(2)把队首元素值插入到队尾;(3)删除队首元素;(4)再次删除队首元素。
直到队列成为空队列为止,得到输出序列:(1)A、C、E、C、C (2) A、C、E(3) A、C、E、C、C、C (4) A、C、E、C3.给出栈的两种存储结构形式名称,在这两种栈的存储结构中如何判别栈空与栈满?4.按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,画出对下列算术表达式求值时操作数栈和运算符栈的变化过程:A-B*C/D+E↑F5.试写一个算法,判断依次读入的一个以@为结束符的字母序列,是否为形如‘序列1& 序列2’模式的字符序列。
其中序列1和序列2中都不含字符’&’,且序列2是序列1的逆序列。
例如,‘a+b&b+a’是属该模式的字符序列,而‘1+3&3-1’则不是。
6.假设表达式由单字母变量和双目四则运算算符构成。
试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰式。
7.假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的队列初始化、入队列和出队列的算法。
8.要求循环队列不损失一个空间全部都能得到利用, 设置一个标志域tag , 以tag为0或1来区分头尾指针相同时的队列状态的空与满,请编写与此结构相应的入队与出队算法。
9.简述以下算法的功能(其中栈和队列的元素类型均为int):(1)void proc_1(Stack S){ int i, n, A[255];n=0;while(!EmptyStack(S)){n++; Pop(&S, &A[n]);}for(i=1; i<=n; i++)Push(&S, A[i]);}(2)void proc_2(Stack S, int e){ Stack T; int d;InitStack(&T);while(!EmptyStack(S)){ Pop(&S, &d);if (d!=e) Push( &T, d);}while(!EmptyStack(T)){ Pop(&T, &d);Push( &S, d);}}(3)void proc_3(Queue *Q){ Stack S; int d;InitStack(&S);while(!EmptyQueue(*Q)){DeleteQueue(Q, &d);Push( &S, d);}while(!EmptyStack(S)){ Pop(&S, &d);EnterQueue(Q,d)}}实习题1.回文判断。
第 1 章绪论课后习题讲解1. 填空⑴()是数据的基本单位,在计算机程序中通常作为一个整体进行考虑与处理。
【解答】数据元素⑵()是数据的最小单位,()是讨论数据结构时涉及的最小数据单位。
【解答】数据项,数据元素【分析】数据结构指的是数据元素以及数据元素之间的关系。
⑶从逻辑关系上讲,数据结构主要分为()、()、()与()。
【解答】集合,线性结构,树结构,图结构⑷数据的存储结构主要有()与()两种基本方法,不论哪种存储结构,都要存储两方面的内容:()与()。
【解答】顺序存储结构,链接存储结构,数据元素,数据元素之间的关系⑸算法具有五个特性,分别是()、()、()、()、()。
【解答】有零个或多个输入,有一个或多个输出,有穷性,确定性,可行性⑹算法的描述方法通常有()、()、()与()四种,其中,()被称为算法语言。
【解答】自然语言,程序设计语言,流程图,伪代码,伪代码⑺在一般情况下,一个算法的时间复杂度是()的函数。
【解答】问题规模⑻设待处理问题的规模为n,若一个算法的时间复杂度为一个常数,则表示成数量级的形式为(),若为n*log25n,则表示成数量级的形式为()。
【解答】Ο(1),Ο(nlog2n)【分析】用大O记号表示算法的时间复杂度,需要将低次幂去掉,将最高次幂的系数去掉。
2. 选择题⑴顺序存储结构中数据元素之间的逻辑关系是由()表示的,链接存储结构中的数据元素之间的逻辑关系是由()表示的。
A 线性结构B 非线性结构C 存储位置D 指针【解答】C,D【分析】顺序存储结构就是用一维数组存储数据结构中的数据元素,其逻辑关系由存储位置(即元素在数组中的下标)表示;链接存储结构中一个数据元素对应链表中的一个结点,元素之间的逻辑关系由结点中的指针表示。
⑵假设有如下遗产继承规则:丈夫与妻子可以相互继承遗产;子女可以继承父亲或母亲的遗产;子女间不能相互继承。
则表示该遗产继承关系的最合适的数据结构应该是()。
第3章链表一、复习要点本章重点讨论最简单的链表结构——单链表。
详细地介绍了单链表的抽象数据类型,单链表的类定义,相应操作的实现,引入了带表头结点的单链表结构。
进一步定义了用模板描述的单链表类。
作为一种应用,讨论了一元多项式的类定义及其加法操作的实现。
此外,讨论了循环链表和双向链表。
在复习这一章时需要对C++ 语言中的指针和引用类型的使用有清楚的理解。
对带表头结点的链表和不带表头结点的链表在插入、删除、搜索时的差别有清楚的认识。
而且需要明确:链表是一种实现级的结构。
本章复习的要点:1、基本知识点单链表是一种线性结构,链表各结点的物理存储可以是不连续的,因此各结点的逻辑次序与物理存放次序可以不一致。
必须理解单链表的定义和特点,单链表的抽象数据类型和类定义,单链表成员函数,如构造函数、搜索、插入、删除等操作的实现,对比带表头结点单链表的搜索、插入、删除操作,比较其优缺点。
其次是循环链表的定义和特点,它与单链表的差别,它的搜索、插入、删除操作的实现。
最后是双向链表的定义,它的插入与删除操作的实现。
2、算法设计单链表的迭代求解算法,包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,在链表中第i个位置插入新结点,删去第i个结点,单链表各结点顺序逆转算法,在单链表中按从左到右和从右到左的顺序遍历的逆转链算法。
带表头结点的单链表的迭代算法,包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,在链表中第i个位置插入新结点,删去第i个结点,连续删除链表中含有value值的结点,两个有序链表的合并。
单链表的递归算法,包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,求链表各结点值的和,求链表各结点的值的平均值。
循环链表的迭代算法:包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,在链表中第i个位置插入新结点,删去第i个结点,将循环链表链入单链表的表头。
第三章栈和队列(参考答案)// 从数据结构角度看,栈和队列是操作受限的线性结构,其顺序存储结构// 和链式存储结构的定义与线性表相同,请参考教材,这里不再重复。
3.1 1 2 3 4 2 1 3 4 3 2 1 4 4 3 2 11 2 4 3 2 1 4 3 3 2 4 11 32 4 23 14 3 4 2 11 3 42 234 11 4 32 2 43 1设入栈序列元素数为n,则可能的出栈序列数为C2n n=(1/n+1)*(2n!/(n!)2)3.2 证明:由j<k和p j<p k说明p j在p k之前出栈,即在k未进栈之前p j已出栈,之后k进栈,然后p k出栈;由j<k和p j>p k说明p j在p k之后出栈,即p j被p k压在下面,后进先出。
由以上两条,不可能存在i<j<k使p j<p k<p i。
也就是说,若有1,2,3顺序入栈,不可能有3,1,2的出栈序列。
3.3 void sympthy(linklist *head, stack *s)//判断长为n的字符串是否中心对称{ int i=1; linklist *p=head->next;while (i<=n/2) // 前一半字符进栈{ push(s,p->data); p=p->next; }if (n % 2 !==0) p=p->next;// 奇数个结点时跳过中心结点while (p && p->data==pop(s)) p=p->next;if (p==null) printf(“链表中心对称”);else printf(“链表不是中心对称”);} // 算法结束3.4int match()//从键盘读入算术表达式,本算法判断圆括号是否正确配对(init s;//初始化栈sscanf(“%c”,&ch);while (ch!=’#’) //’#’是表达式输入结束符号switch (ch){ case ’(’: push(s,ch); break;case ’)’: if (empty(s)) {printf(“括号不配对”); exit(0);}pop(s);}if (!empty(s)) printf(“括号不配对”);else printf(“括号配对”);} // 算法结束3.5typedef struct // 两栈共享一向量空间{ ElemType v[m]; // 栈可用空间0—m-1int top[2] // 栈顶指针}twostack;int push(twostack *s,int i, ElemType x)// 两栈共享向量空间,i是0或1,表示两个栈,x是进栈元素,// 本算法是入栈操作{ if (abs(s->top[0] - s->top[1])==1) return(0);// 栈满else {switch (i){case 0: s->v[++(s->top)]=x; break;case 1: s->v[--(s->top)]=x; break;default: printf(“栈编号输入错误”); return(0);}return(1); // 入栈成功}} // 算法结束ElemType pop(twostack *s,int i)// 两栈共享向量空间,i是0或1,表示两个栈,本算法是退栈操作{ ElemType x;if (i!=0 && i!=1) return(0);// 栈编号错误else {switch (i){case 0: if(s->top[0]==-1) return(0);//栈空else x=s->v[s->top--];break;case 1: if(s->top[1]==m) return(0);//栈空else x=s->v[s->top++]; break;default: printf(“栈编号输入错误”);return(0);}return(x); // 退栈成功}} // 算法结束ElemType top (twostack *s,int i)// 两栈共享向量空间,i是0或1,表示两个栈,本算法是取栈顶元素操作{ ElemType x;switch (i){case 0: if(s->top[0]==-1) return(0);//栈空else x=s->v[s->top]; break;case 1: if(s->top[1]==m) return(0);//栈空else x=s->v[s->top]; break;default: printf(“栈编号输入错误”);return(0);}return(x); // 取栈顶元素成功} // 算法结束3.6void Ackerman(int m,int n)// Ackerman 函数的递归算法{ if (m==0) return(n+1);else if (m!=0 && n==0) return(Ackerman(m-1,1);else return(Ackerman(m-1,Ackerman(m,n-1))} // 算法结束3.7(1) linklist *init(linklist *q)// q是以带头结点的循环链表表示的队列的尾指针,本算法将队列置空{ q=(linklist *)malloc(sizeof(linklist));//申请空间,不判断空间溢出q->next=q;return (q);} // 算法结束(2) linklist *enqueue(linklist *q,ElemType x)// q是以带头结点的循环链表表示的队列的尾指针,本算法将元素x入队{ s=(linklist *)malloc(sizeof(linklist));//申请空间,不判断空间溢出s->next=q->next; // 将元素结点s入队列q->next=s;q=s; // 修改队尾指针return (q);} // 算法结束(3) linklist *delqueue(linklist *q)//q是以带头结点的循环链表表示的队列的尾指针,这是出队算法{ if (q==q->next) return (null); // 判断队列是否为空else {linklist *s=q->next->next; // s指向出队元素if (s==q) q=q->next; // 若队列中只一个元素,置空队列else q->next->next=s->next;// 修改队头元素指针free (s); // 释放出队结点}return (q);} // 算法结束。
第3章栈和队列习题1.选择题(1)若让元素1,2,3,4,5依次进栈,则出栈次序不可能出现在()种情况。
A.5,4,3,2,1 B.2,1,5,4,3 C.4,3,1,2,5 D.2,3,5,4,1(2)若已知一个栈的入栈序列是1,2,3,…,n,其输出序列为p1,p2,p3,…,pn,若p1=n,则pi为()。
A.i B.n-i C.n-i+1 D.不确定(3)数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素个数的公式为()。
A.r-f B.(n+f-r)%n C.n+r-f D.(n+r-f)%n (4)链式栈结点为:(data,link),top指向栈顶.若想摘除栈顶结点,并将删除结点的值保存到x中,则应执行操作()。
A.x=top->data;top=top->link; B.top=top->link;x=top->link;C.x=top;top=top->link; D.x=top->link;(5)设有一个递归算法如下int fact(int n) { //n大于等于0if(n<=0) return 1;else return n*fact(n-1); }则计算fact(n)需要调用该函数的次数为()。
A. n+1 B. n-1 C. n D. n+2 (6)栈在()中有所应用。
A.递归调用 B.函数调用 C.表达式求值 D.前三个选项都有(7)为解决计算机主机与打印机间速度不匹配问题,通常设一个打印数据缓冲区。
主机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区中取出数据。
该缓冲区的逻辑结构应该是()。
A.队列 B.栈 C.线性表 D.有序表(8)设栈S和队列Q的初始状态为空,元素e1、e2、e3、e4、e5和e6依次进入栈S,一个元素出栈后即进入Q,若6个元素出队的序列是e2、e4、e3、e6、e5和e1,则栈S的容量至少应该是()。
选择题第3章线性表的链式存储(1)两个有序线性表分别具有n个元素与m个元素且n≤m,现将其归并成一个有序表,其最少的比较次数是( A )。
A.n B.m C.n− 1D.m + n(2)非空的循环单链表 head 的尾结点(由 p 所指向)满足( C )。
A.p->next==NULL B.p==NULL C.p->next==head D.p==head(3)在带头结点的单链表中查找x应选择的程序体是( C )。
A.node *p=head->next; while (p && p->info!=x) p=p->next;if (p->info==x) return p else return NULL;B.node *p=head; while (p&& p->info!=x) p=p->next; return p;C.node *p=head->next; while (p&&p->info!=x) p=p->next; return p;D.node *p=head; while (p->info!=x) p=p->next ; return p;(4)线性表若采用链式存储结构时,要求内存中可用存储单元的地址( D )。
A.必须是连续的C.一定是不连续的B.部分地址必须是连续的D.连续不连续都可以(5)在一个具有n个结点的有序单链表中插入一个新结点并保持单链表仍然有序的时间复杂度是( B )。
A.O(1) B.O(n)C.O(n2)D.O(n log2n)(6)用不带头结点的单链表存储队列时,其队头指针指向队头结点,其队尾指针指向队尾结点,则在进行删除操作时(D )。
A.仅修改队头指针C.队头、队尾指针都要修改B.仅修改队尾指针D.队头,队尾指针都可能要修改(7)若从键盘输入n个元素,则建立一个有序单向链表的时间复杂度为( B )。
习题31.填空题(1)栈的进出原则是(___________),队列的进出原则是(___________)。
答案:后进先出(LIFO)先进先出(FIFO)(2)设32位计算机系统中,空栈S存储int型数据,栈顶指针为1024H。
经过操作序列push(1),push(2),pop,push(5),push(7),pop,push(6)之后,栈顶元素为(___________),栈底元素为(___________),栈的高度为(___________),输出序列是(___________),栈顶指针为(___________)H。
答案:6 1 3 2,7 1030(3)两栈共享存储空间,其数组大小为100,数组下标从0开始。
top1和top2分别为栈1和栈2的栈顶元素下标,则栈1为空的条件为(___________),栈2为空的条件为(___________),栈1或栈2满的条件为(___________)。
答案:top1==-1 top2==100 top1+1==top2(4)一个队列的入队顺序是1234,则队列的输出顺序是(___________)。
答案:1234(5)设循环队列数组大小为100,队头指针为front,队尾指针为rear;约定front指向队头元素的前一个位置,该位置永远不存放数据。
则入队操作时,修改rear=(___________),出队操作修改front=(___________),队空的判别条件为(___________),队满的判别条件为(___________)。
若front=20,rear=60,则队列长度为(___________),若front=60,rear=20,则队列长度为(___________)。
答案:(rear+1)%100 (front+1)%100 rear==front (rear+1)%100=front 40 60(6)朴素模式匹配算法中,每个串的起始下标均为1,变量i=100,j=10,分别表示主串和模式串当前比较的字符元素下标,若本次比较两字符不同,则i回溯为(___________),j 回溯为(___________)。
3.1 选择题第3章线性表的链式存储(1)两个有序线性表分别具有n个元素与m个元素且n≤m,现将其归并成一个有序表,其最少的比较次数是( A )。
A.n B.m C.n− 1 D.m + n(2)非空的循环单链表 head 的尾结点(由 p 所指向)满足( C )。
A.p->next==NULL B.p==NULL C.p->next==head D.p==head (3)在带头结点的单链表中查找x应选择的程序体是( C )。
A.node *p=head->next; while (p && p->info!=x) p=p->next;if (p->info==x) return p else return NULL;B.node *p=head; while (p&& p->info!=x) p=p->next; return p;C.node *p=head->next; while (p&&p->info!=x) p=p->next; return p;D.node *p=head; while (p->info!=x) p=p->next ; return p;(4)线性表若采用链式存储结构时,要求内存中可用存储单元的地址( D )。
A.必须是连续的C.一定是不连续的B.部分地址必须是连续的D.连续不连续都可以(5)在一个具有n个结点的有序单链表中插入一个新结点并保持单链表仍然有序的时间复杂度是( B )。
A.O(1) B.O(n) C.O(n2) D.O(n log2n)(6)用不带头结点的单链表存储队列时,其队头指针指向队头结点,其队尾指针指向队尾结点,则在进行删除操作时(D )。
A.仅修改队头指针C.队头、队尾指针都要修改B.仅修改队尾指针D.队头,队尾指针都可能要修改(7)若从键盘输入n个元素,则建立一个有序单向链表的时间复杂度为( B )。
head 11级计本、信本第3章 栈和队列 自测卷答案一、填空题(每空1分,共15分)1.向量、栈和队列都是 线性 结构,可以在向量的 任何 位置插入和删除元素;对于栈只能在 栈顶 插入和删除元素;对于队列只能在 队尾 插入和 队首 删除元素。
2. 栈是一种特殊的线性表,允许插入和删除运算的一端称为 栈顶 。
不允许插入和删除运算的一端称为 栈底 。
3. 队列 是被限定为只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表。
4. 在一个循环队列中,队首指针指向队首元素的 前一个 位置。
5. 在具有n 个单元的循环队列中,队满时共有 n-1 个元素。
6. 向栈中压入元素的操作是先 移动栈顶指针 ,后 存入元素 。
7. 从循环队列中删除一个元素时,其操作是 先 移动队首指针 ,后 取出元素 。
8.带表头结点的空循环双向链表的长度等于 0 。
解:二、判断正误(判断下列概念的正确性,并作出简要的说明。
)(每小题1分,共10分)( × )1. 线性表的每个结点只能是一个简单类型,而链表的每个结点可以是一个复杂类型。
错,线性表是逻辑结构概念,可以顺序存储或链式存储,与元素数据类型无关。
( × )2. 在表结构中最常用的是线性表,栈和队列不太常用。
错,不一定吧?调用子程序或函数常用,CPU 中也用队列。
( √ )3. 栈是一种对所有插入、删除操作限于在表的一端进行的线性表,是一种后进先出型结构。
( √ )4. 对于不同的使用者,一个表结构既可以是栈,也可以是队列,也可以是线性表。
正确,都是线性逻辑结构,栈和队列其实是特殊的线性表,对运算的定义略有不同而已。
( × )5. 栈和链表是两种不同的数据结构。
错,栈是逻辑结构的概念,是特殊殊线性表,而链表是存储结构概念,二者不是同类项。
( × )6. 栈和队列是一种非线性数据结构。
错,他们都是线性逻辑结构,栈和队列其实是特殊的线性表,对运算的定义略有不同而已。
第 3 章特殊线性表——栈、队列和串2005-07-14第 3 章特殊线性表——栈、队列和串课后习题讲解1. 填空⑴设有一个空栈,栈顶指针为1000H,现有输入序列为1、2、3、4、5,经过push,push,pop,push,pop,push,push后,输出序列是(),栈顶指针为()。
【解答】23,1003H⑵栈通常采用的两种存储结构是();其判定栈空的条件分别是(),判定栈满的条件分别是()。
【解答】顺序存储结构和链接存储结构(或顺序栈和链栈),栈顶指针top= -1和top=NULL,栈顶指针top等于数组的长度和内存无可用空间⑶()可作为实现递归函数调用的一种数据结构。
【解答】栈【分析】递归函数的调用和返回正好符合后进先出性。
⑷表达式a*(b+c)-d的后缀表达式是()。
【解答】abc+*d-【分析】将中缀表达式变为后缀表达式有一个技巧:将操作数依次写下来,再将算符插在它的两个操作数的后面。
⑸栈和队列是两种特殊的线性表,栈的操作特性是(),队列的操作特性是(),栈和队列的主要区别在于()。
【解答】后进先出,先进先出,对插入和删除操作限定的位置不同⑹循环队列的引入是为了克服()。
【解答】假溢出⑺数组Q[n]用来表示一个循环队列,front为队头元素的前一个位置,rear为队尾元素的位置,计算队列中元素个数的公式为()。
【解答】(rear-front+n)% n【分析】也可以是(rear-front)% n,但rear-front的结果可能是负整数,而对一个负整数求模,其结果在不同的编译器环境下可能会有所不同。
⑻用循环链表表示的队列长度为n,若只设头指针,则出队和入队的时间复杂度分别是()和()。
【解答】O(1),O(n)【分析】在带头指针的循环链表中,出队即是删除开始结点,这只需修改相应指针;入队即是在终端结点的后面插入一个结点,这需要从头指针开始查找终端结点的地址。
⑼串是一种特殊的线性表,其特殊性体现在()。
第三章习题1、按图3、1(b)所示铁道(两侧铁道均为单向行驶道)进行车厢调度,回答:⑴如进站得车厢序列为123,则可能得到得出站车厢序列就是什么?⑵如进站得车厢序列为123456,能否得到435612与135426得出站序列,并说明原因。
(即写出以“S”表示进栈、以“X”表示出栈得栈操作序列)。
2、设队列中有A、B、C、D、E这5个元素,其中队首元素为A。
如果对这个队列重复执行下列4步操作:(1)输出队首元素;(2)把队首元素值插入到队尾;(3)删除队首元素;(4)再次删除队首元素。
直到队列成为空队列为止,得到输出序列:(1)A、C、E、C、C (2) A、C、E(3) A、C、E、C、C、C (4) A、C、E、C3、给出栈得两种存储结构形式名称,在这两种栈得存储结构中如何判别栈空与栈满?4、按照四则运算加、减、乘、除与幂运算(↑)优先关系得惯例,画出对下列算术表达式求值时操作数栈与运算符栈得变化过程:A-B*C/D+E↑F5、试写一个算法,判断依次读入得一个以为结束符得字母序列,就是否为形如‘序列1& 序列2’模式得字符序列。
其中序列1与序列2中都不含字符’&’,且序列2就是序列1得逆序列。
例如,‘a+b&b+a’就是属该模式得字符序列,而‘1+3&3-1’则不就是。
6、假设表达式由单字母变量与双目四则运算算符构成。
试写一个算法,将一个通常书写形式且书写正确得表达式转换为逆波兰式。
7、假设以带头结点得循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应得队列初始化、入队列与出队列得算法。
8、要求循环队列不损失一个空间全部都能得到利用, 设置一个标志域tag , 以tag为0或1来区分头尾指针相同时得队列状态得空与满,请编写与此结构相应得入队与出队算法。
9、简述以下算法得功能(其中栈与队列得元素类型均为int):(1)void proc_1(Stack S){ int i, n, A[255];n=0;while(!EmptyStack(S)){n++; Pop(&S, &A[n]);} for(i=1; i<=n; i++)Push(&S, A[i]);}(2)void proc_2(Stack S, int e){ Stack T; int d;InitStack(&T);while(!EmptyStack(S)){ Pop(&S, &d);if (d!=e) Push( &T, d);}while(!EmptyStack(T)){ Pop(&T, &d);Push( &S, d);}}(3)void proc_3(Queue *Q){ Stack S; int d;InitStack(&S);while(!EmptyQueue(*Q)){DeleteQueue(Q, &d);Push( &S, d);}while(!EmptyStack(S)){ Pop(&S, &d);EnterQueue(Q,d)}}实习题1.回文判断。
3.5习题一、名词解释(1)栈栈是限制在表的一端进行插入和删除操作的线性表。
允许插入、删除的这一端称为栈顶,另一个固定端称为栈底。
栈的顺序结构:利用顺序存储方式实现的栈称为顺序栈。
栈的链式结构:用链式存储结构实现的栈称为链栈。
(2)队队是一种“先进先出” (FIFO---First In First Out)的数据结构,即插入操作在表一端进行,而删除操作在表的另一端进行,这种数据结构称为队列。
把允许插入的一端称为队尾(rear),把允许删除的一端称为队头(front)。
队的顺序结构:顺序存储的队称为顺序队。
队的链式结构:采用链式存储结构的队称为链队。
二、判断题(1)栈和队列都是特殊的线性表。
( √ )(2)栈和队列都将插入和删除操作限制在表的端点处进行。
(√ )(3)只允许在表的一端进行插入和删除操作的线性表称为栈。
(√)(4)没有元素的栈称为空栈,空栈用不着栈顶指针。
( × )(5)只要栈不空,就能任意删除栈的元素。
(× )(6)栈允许删除的一端称为栈顶,而栈底元素是不能删除的。
(× )(7)对采用链式存储结构的栈进行操作不必判断溢出。
(√ )(8)元素进出队列一定满足“先进先出”的规律。
(√ )(9)链队列不存在溢出问题。
(√ )(10)在链队列中删除一个元素是在链表的最前端进行的。
(√ )三、单项选择题(1)栈和队列的共同之处在于它们具有相同的( A )。
A.逻辑特性 B.物理特性 C.运算方法 D.元素类型(2)栈和队列都是特殊的线性表,其特殊性在于( C )。
A.它们具有一般线性表所没有的逻辑特性B.它们的存储结构比较特殊C.对它们的使用方法做了限制D.它们比一般线性表更简单(3)若5个元素的出栈序列为1,2,3,4,5,则进栈序列可能是( )。
A.2,4,3,1,5 B.2,3,1,5,4C.3,1,4,2,5 D.3,1,2,5,4(4)某队列初始为空,若它的输入序列为a,b,c,d,它的输出序列应为( )。
第3章习题解答3.1与顺序表相比线性链表有哪些优点?又有哪些局限?若线性表为空,对应的链表是否一定没有结点?[解答]与顺序表相比线性链表的明显优点是:1能够灵活利用存储空间,因为它不是依靠线性表中的数据元素在内存中的相互位置关系来表示数据元素间的逻辑关系,因此它的存储空间可以不连续,从而有利于离散空间的充分利用;2由于在线性链表中是通过结点中的指针来指示数据元素之间的逻辑关系的,因此在作插入、删除等操作的时候避免了数据元素平移的操作,从而可以提高运算实现的效率。
3由于线性链表所占的存储空间完全由表结点的个数决定,当需要增加或减少表中的数据元素时,表空间很容易扩充和缩小。
当然也就不会出现顺序表中存在的表空间扩充困难或者是表空间利用不充分的问题。
线性链表的局限主要是:因为它是依靠跟在数据元素后边的指针来表示数据元素之间的逻辑关系的,因此每个数据元素除了本身的存储空间之外还需要有存放指针的空间,即它比顺序表要付出更多的空间代价。
当约定线性链表不带表头结点的情况下,线性表为空时,对应的链表也没有结点。
3.2链式栈和顺序栈在操作上的主要差别是什么?为什么说对于空闲存储空间的管理适宜采用链式栈来实现?[解答]由顺序栈和链式栈的结构特点可知,顺序栈是顺序存储结构,对其实现基本操作是在连续的存储空间上进行的,因此顺序栈的入栈、出栈、读栈顶元素等操作主要是通过控制栈顶指针的位置来实现的,也就是说,移动栈顶指针是实现顺序栈的基本运算的主要操作。
链式栈是一种链式存储结构,因此它具有链式存储结构的基本特点,它的基本运算主要是通过控制栈顶指针和修改栈顶结点的指针域的值来实现,也就是说,链式栈的基本运算主要是通过改变栈顶指针和栈顶结点中的指针来实现的。
对于链式存储结构来说,空闲的存储空间为各链表所共享,当有新元素要加入链表时,需要从空闲空间取得结点,再把新元素放入空闲结点,然后把新结点加入到链表中;相反地,当从链表中删除元素时,要释放被删除结点到空闲空间。
第三章特殊线表习题
一、选择题
1、若用单链表来表示队列,则应该选用。
A、带尾指针的非循环链表
B、带尾指针的循环链表
C、带头指针的非循环链表
D、带头指针的循环链表
2、若用一个大小为6的数组来实现循环队列,且当rear和front的值分别为0和3。
当从队列中删除一个元素,再加入两个元素后,rear 和front的值分别是。
A、1和5
B、2和4
C、4和2
D、5和1
3、设栈的输入序列为1、2、3、4,则不可能是其出栈序列。
A、1243
B、2134
C、1432
D、4312
E、3214
4、已知一算术表达式的中缀形式为A+B*C-D/E,后缀形式为ABC*+DE/-,其前缀形式为。
A、-A+B*C/DE
B、-A+B*CD/E
C、-+*ABC/DE
D、-+A*BC/DE
5、设栈的输入序列是1、2、…、n,若输出序列的第一个元素是n,则第i个输出元素是。
A、不确定
B、n-i+1
C、i
D、n-i
6、假定一个顺序循环队列的队首和队尾指针分别用front 和rear表示,则判队空的条件是。
A、front+1==rear
B、front==rear+1
C、front==0
D、front==rear
7、假定一个顺序循环队列存储于数组A[n]中,其队首和队尾指针分别用front 和rear表示,则判断队满的条件是。
A、(rear-1)%n==front
B、(rear+1)%n==front
C、rear==(front-1)%n
D、rear==(front+1)%n
8、一个栈的的输入序列为12345,则下列序列中不可能是栈的输出序列的是。
A、23415
B、54132
C、23145
D、15432
9、若一个栈的输入序列是1、2、3、…、n,输出序列的第一个元素是i,则第i个输出元素是。
A、i-j-1
B、i-j
C、j-i+1
D、不确定
10、用单链表表示的链式队列的队头在链表的位置。
A、链头
B、链尾
C、链中
11、设计一个判别表达式中左、右括号是否配对出现的算法,采用数据结构最佳。
A、线性表的顺序存储结构
B、队列
C、线性表的链式存储结构
D、栈
12、在下列算法描述中,涉及到队运算的算法是 D 。
A、表达式求值算法
B、深度优先搜索
C、二叉树遍历
D、广度优先搜索
13、栈的插入和删除操作在进行。
A、栈顶
B、栈底
C、任意位置
D、指定位置
14、在一个顺序循环队列中,队首指针指向队首元素的位置。
A、前一个
B、后一个
C、当前
D、最后
15、当利用大小为N的数组存储顺序循环队列时,该队列的最大长度为。
A、N-2
B、N-1
C、N
D、N+1
16、如果以链表作为栈的存储结构,则退栈操作时。
A、必须判别栈是否满
B、判别栈元素的类型
C、必须判别栈是否空
D、对栈不作任何判别
17、链栈与顺序栈相比有一个明显的优点,即。
A、插入操作更加方便
B、通常不会出现栈满的情况
C、不会出现栈空的情况
D、删除操作更加方便
二、填空题
1、中缀式a+b*3+4*(c-d)对应的前缀式为 ++a×b3×4-cd ,若a=1,b=2,c=3,d=4,则后缀式db/cc*a-b*+的运算结果为 18 。
2、用下标0开始的N元数组实现循环队列时,为实现下标变量m加1后在数组有效下标范围内循环,可采用的表达式是m= (m+1)% n 。
3、表达式求值是栈应用的一个典型例子。
4、队列是特殊的线性表,其特殊性在于只允许在表的一端进行元素的插入而在另一端进行元素的删除。
5、一个循环队列存于A[M]中,假定队首和队尾指针分别为front和rear,则判断队空的条件为 front==rear ,判断队满的条件为 (rear+1) % M==front 。
6、向一个循环队列存入新元素时,需要首先移动队尾指针,然后再向它所指位置存入新元素。
7、队列又称为先进先出表。
8、栈是特殊的线性表,其特殊性在于只允许在栈顶加入或删除元素。
9、栈又称为后进先出表,队列又成为先进先出表。
10、在一个用一维数组A[N]表示的顺序栈中,该栈所含元素的个数最少为0 个,最多为 N 个。
11、在一个用一维数组A[N]表示的循环队列中,该队列中的元素个数最少为0 个,最多为 N-1 个。