数据结构(c语言版)_严蔚敏版_第3章_栈和队列_信大(第3讲)
严蔚敏数据结构c语言版_习题答案
while(result.sport!=NULL)
{
switch(result.schoolname)
{
case 'A':
score[ 0 ].totalscore+=result.score;
if(result.gender==0) score[ 0 ].malescore+=result.score;
{
for(i=1;i<=A.length&&i<=B.length;i++)
if(A.elem[i]!=B.elem[i])
return A.elem[i]>B.elem[i]?1:-1;
if(A.length==B.length) return 0;
return A.length>B.length?1:-1; //当两个字符表可以互相比较的部分完全相同时,哪个较长,哪个就较大
sum=1;
j=0;
for(i=k+1;i<=m;i++,j++) //求出序列第k至第m个元素的值
temp=2*sum-temp[j];
f=temp[m];
}
return OK;
}//fib
分析: k阶斐波那契序列的第m项的值f[m]=f[m-1]+f[m-2]+......+f[m-k]
while(p->next) p=p->next;
p->next=hb;
}//ListConcat
2.16
见书后答案.
2.17
严蔚敏《数据结构》(C语言版)教材精讲(栈与队列)【圣才出品】
if(! S.bottom) return ERROR;
S.top=S.bottom+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top=e; S.top++; /* 栈顶指针加 1,e 成为新的栈顶 */ return OK; }
改是按后迕先出的原则迕行的。 进栈(push)
出栈(pop)
top
an ⋯⋯ ai ⋯⋯
图 3-1 顺序栈示意图
2.栈的抽象数据类型定义
ADT Stack {
数据对象:D={ ai|ai∈ElemSet,i=1,2,…,n,n≥0} 数据关系:R={<ai-1,ai>|ai-1,ai∈D,i=2,3,…,n} 基本操作:初始化、进栈、出栈、取栈顶元素等 }ADT Stack
1.栈的动态顺序存储表示 采用动态一维数组来存储栈。所谓动态,指的是栈的大小可以根据需要增加。 ①用 bottom 表示栈底指针,栈底固定丌变的;用 top 表示栈顶指针,栈顶则随着迕 栈和退栈操作而变化。 ②用 top=bottom 作为栈空的标记,每次 top 指向栈顶数组中的下一个存储位置。 ③结点迕栈:首先将数据元素保存到栈顶(top 所指的当前位置),然后执行 top 加 1, 使 top 指向栈顶的下一个存储位置; ④结点出栈:首先执行 top 减 1,使 top 指向栈顶元素的存储位置,然后将栈顶元素 取出。 动态堆栈变化示意图如图 3-2 所示。
基本操作的实现: ①栈的类型定义
严蔚敏《数据结构(c语言版)习题集》答案第三章 栈与队列
第三章栈与队列3.15typedef struct{Elemtype *base[2];Elemtype *top[2];}BDStacktype; //双向栈类型Status Init_Stack(BDStacktype &tws,int m)//初始化一个大小为m的双向栈tws{tws.base[0]=(Elemtype*)malloc(sizeof(Elemtype));tws.base[1]=tws.base[0]+m;tws.top[0]=tws.base[0];tws.top[1]=tws.base[1];return OK;}//Init_StackStatus push(BDStacktype &tws,int i,Elemtype x)//x入栈,i=0表示低端栈,i=1表示高端栈{if(tws.top[0]>tws.top[1]) return OVERFLOW; //注意此时的栈满条件if(i==0) *tws.top[0]++=x;else if(i==1) *tws.top[1]--=x;else return ERROR;return OK;}//pushStatus pop(BDStacktype &tws,int i,Elemtype &x)//x出栈,i=0表示低端栈,i=1表示高端栈{if(i==0){if(tws.top[0]==tws.base[0]) return OVERFLOW;x=*--tws.top[0];}else if(i==1){if(tws.top[1]==tws.base[1]) return OVERFLOW;x=*++tws.top[1];}else return ERROR;return OK;}//pop3.16void Train_arrange(char *train)//这里用字符串train表示火车,'H'表示硬席,'S'表示软席{p=train;q=train;InitStack(s);while(*p){if(*p=='H') push(s,*p); //把'H'存入栈中else *(q++)=*p; //把'S'调到前部p++;}while(!StackEmpty(s)){pop(s,c);*(q++)=c; //把'H'接在后部}}//Train_arrange3.17int IsReverse()//判断输入的字符串中'&'前和'&'后部分是否为逆串,是则返回1,否则返回0{InitStack(s);while((e=getchar())!='&')push(s,e);while((e=getchar())!='@'){if(StackEmpty(s)) return 0;pop(s,c);if(e!=c) return 0;}if(!StackEmpty(s)) return 0;return 1;}//IsReverse3.18Status Bracket_Test(char *str)//判别表达式中小括号是否匹配{count=0;for(p=str;*p;p++){if(*p=='(') count++;else if(*p==')') count--;if (count<0) return ERROR;}if(count) return ERROR; //注意括号不匹配的两种情况return OK;}//Bracket_Test3.19Status AllBrackets_Test(char *str)//判别表达式中三种括号是否匹配{InitStack(s);for(p=str;*p;p++){if(*p=='('||*p=='['||*p=='{') push(s,*p);else if(*p==')'||*p==']'||*p=='}'){if(StackEmpty(s)) return ERROR;pop(s,c);if(*p==')'&&c!='(') return ERROR;if(*p==']'&&c!='[') return ERROR;if(*p=='}'&&c!='{') return ERROR; //必须与当前栈顶括号匹配}}//forif(!StackEmpty(s)) return ERROR;return OK;}//AllBrackets_Test3.20typedef struct {. int x;int y;} coordinate;void Repaint_Color(int g[m][n],int i,int j,int color)//把点(i,j)相邻区域的颜色置换为color{old=g[i][j];InitQueue(Q);EnQueue(Q,{I,j});while(!QueueEmpty(Q)){DeQueue(Q,a);x=a.x;y=a.y;if(x>1)if(g[x-1][y]==old){g[x-1][y]=color;EnQueue(Q,{x-1,y}); //修改左邻点的颜色}if(y>1)if(g[x][y-1]==old){g[x][y-1]=color;EnQueue(Q,{x,y-1}); //修改上邻点的颜色}if(x<m)if(g[x+1][y]==old){g[x+1][y]=color;EnQueue(Q,{x+1,y}); //修改右邻点的颜色}if(y<n)if(g[x][y+1]==old){g[x][y+1]=color;EnQueue(Q,{x,y+1}); //修改下邻点的颜色}}//while}//Repaint_Color分析:本算法采用了类似于图的广度优先遍历的思想,用两个队列保存相邻同色点的横坐标和纵坐标.递归形式的算法该怎么写呢?3.21void NiBoLan(char *str,char *new)//把中缀表达式str转换成逆波兰式new{p=str;q=new; //为方便起见,设str的两端都加上了优先级最低的特殊符号InitStack(s); //s为运算符栈while(*p){if(*p是字母)) *q++=*p; //直接输出else{c=gettop(s);if(*p优先级比c高) push(s,*p);else{while(gettop(s)优先级不比*p低){pop(s,c);*(q++)=c;}//whilepush(s,*p); //运算符在栈内遵循越往栈顶优先级越高的原则}//else}//elsep++;}//while}//NiBoLan //参见编译原理教材3.22int GetValue_NiBoLan(char *str)//对逆波兰式求值{p=str;InitStack(s); //s为操作数栈while(*p){if(*p是数) push(s,*p);else{pop(s,a);pop(s,b);r=compute(b,*p,a); //假设compute为执行双目运算的过程push(s,r);}//elsep++;}//whilepop(s,r);return r;}//GetValue_NiBoLan3.23Status NiBoLan_to_BoLan(char *str,stringtype &new)//把逆波兰表达式str转换为波兰式new{p=str;Initstack(s); //s的元素为stringtype类型while(*p){if(*p为字母) push(s,*p);else{if(StackEmpty(s)) return ERROR;pop(s,a);if(StackEmpty(s)) return ERROR;pop(s,b);c=link(link(*p,b),a);push(s,c);}//elsep++;}//whilepop(s,new);if(!StackEmpty(s)) return ERROR;return OK;}//NiBoLan_to_BoLan分析:基本思想见书后注释.本题中暂不考虑串的具体操作的实现,而将其看作一种抽象数据类型stringtype,对其可以进行连接操作:c=link(a,b).3.24Status g(int m,int n,int &s)//求递归函数g的值s{if(m==0&&n>=0) s=0;else if(m>0&&n>=0) s=n+g(m-1,2*n);else return ERROR;return OK;}//g3.25Status F_recursive(int n,int &s)//递归算法{if(n<0) return ERROR;if(n==0) s=n+1;else{F_recurve(n/2,r);s=n*r;}return OK;}//F_recursiveStatus F_nonrecursive(int n,int s)//非递归算法{if(n<0) return ERROR;if(n==0) s=n+1;else{InitStack(s); //s的元素类型为struct {int a;int b;}while(n!=0){a=n;b=n/2;push(s,{a,b});n=b;}//whiles=1;while(!StackEmpty(s)){pop(s,t);s*=t.a;}//while}return OK;}//F_nonrecursive3.26float Sqrt_recursive(float A,float p,float e)//求平方根的递归算法{if(abs(p^2-A)<=e) return p;else return sqrt_recurve(A,(p+A/p)/2,e);}//Sqrt_recurvefloat Sqrt_nonrecursive(float A,float p,float e)//求平方根的非递归算法{while(abs(p^2-A)>=e)p=(p+A/p)/2;return p;}//Sqrt_nonrecursive3.27这一题的所有算法以及栈的变化过程请参见《数据结构(pascal版)》,作者不再详细写出.3.28void InitCiQueue(CiQueue &Q)//初始化循环链表表示的队列Q{Q=(CiLNode*)malloc(sizeof(CiLNode));Q->next=Q;}//InitCiQueuevoid EnCiQueue(CiQueue &Q,int x)//把元素x插入循环链表表示的队列Q,Q指向队尾元素,Q->next指向头结点,Q->next->next指向队头元素{p=(CiLNode*)malloc(sizeof(CiLNode));p->data=x;p->next=Q->next; //直接把p加在Q的后面Q->next=p;Q=p; //修改尾指针}Status DeCiQueue(CiQueue &Q,int x)//从循环链表表示的队列Q头部删除元素x{if(Q==Q->next) return INFEASIBLE; //队列已空p=Q->next->next;x=p->data;Q->next->next=p->next;free(p);return OK;}//DeCiQueue3.29Status EnCyQueue(CyQueue &Q,int x)//带tag域的循环队列入队算法{if(Q.front==Q.rear&&Q.tag==1) //tag域的值为0表示"空",1表示"满"return OVERFLOW;Q.base[Q.rear]=x;Q.rear=(Q.rear+1)%MAXSIZE;if(Q.front==Q.rear) Q.tag=1; //队列满}//EnCyQueueStatus DeCyQueue(CyQueue &Q,int &x)//带tag域的循环队列出队算法{if(Q.front==Q.rear&&Q.tag==0) return INFEASIBLE;Q.front=(Q.front+1)%MAXSIZE;x=Q.base[Q.front];if(Q.front==Q.rear) Q.tag=1; //队列空return OK;}//DeCyQueue分析:当循环队列容量较小而队列中每个元素占的空间较多时,此种表示方法可以节约较多的存储空间,较有价值.3.30Status EnCyQueue(CyQueue &Q,int x)//带length域的循环队列入队算法{if(Q.length==MAXSIZE) return OVERFLOW;Q.rear=(Q.rear+1)%MAXSIZE;Q.base[Q.rear]=x;Q.length++;return OK;}//EnCyQueueStatus DeCyQueue(CyQueue &Q,int &x)//带length域的循环队列出队算法{if(Q.length==0) return INFEASIBLE;head=(Q.rear-Q.length+1)%MAXSIZE; //详见书后注释x=Q.base[head];Q.length--;}//DeCyQueue3.31int Palindrome_Test()//判别输入的字符串是否回文序列,是则返回1,否则返回0{InitStack(S);InitQueue(Q);while((c=getchar()!='@'){Push(S,c);EnQueue(Q,c); //同时使用栈和队列两种结构}while(!StackEmpty(S)){Pop(S,a);DeQueue(Q,b));if(a!=b) return ERROR;}return OK;}//Palindrome_Test3.32void GetFib_CyQueue(int k,int n)//求k阶斐波那契序列的前n+1项{InitCyQueue(Q); //其MAXSIZE设置为kfor(i=0;i<k-1;i++) Q.base[i]=0;Q.base[k-1]=1; //给前k项赋初值for(i=0;i<k;i++) printf("%d",Q.base[i]);for(i=k;i<=n;i++){m=i%k;sum=0;for(j=0;j<k;j++) sum+=Q.base[(m+j)%k];Q.base[m]=sum; //求第i项的值存入队列中并取代已无用的第一项printf("%d",sum);}}//GetFib_CyQueue3.33Status EnDQueue(DQueue &Q,int x)//输出受限的双端队列的入队操作{if((Q.rear+1)%MAXSIZE==Q.front) return OVERFLOW; //队列满avr=(Q.base[Q.rear-1]+Q.base[Q.front])/2;if(x>=avr) //根据x的值决定插入在队头还是队尾{Q.base[Q.rear]=x;Q.rear=(Q.rear+1)%MAXSIZE;} //插入在队尾else{Q.front=(Q.front-1)%MAXSIZE;Q.base[Q.front]=x;} //插入在队头return OK;}//EnDQueueStatus DeDQueue(DQueue &Q,int &x)//输出受限的双端队列的出队操作{if(Q.front==Q.rear) return INFEASIBLE; //队列空x=Q.base[Q.front];Q.front=(Q.front+1)%MAXSIZE;return OK;}//DeDQueue3.34void Train_Rearrange(char *train)//这里用字符串train表示火车,'P'表示硬座,'H'表示硬卧,'S'表示软卧,最终按PSH的顺序排列{r=train;InitDQueue(Q);while(*r){if(*r=='P'){printf("E");printf("D"); //实际上等于不入队列,直接输出P车厢 }else if(*r=='S'){printf("E");EnDQueue(Q,*r,0); //0表示把S车厢从头端入队列}else{printf("A");EnDQueue(Q,*r,1); //1表示把H车厢从尾端入队列}}//whilewhile(!DQueueEmpty(Q)){printf("D");DeDQueue(Q);}//while //从头端出队列的车厢必然是先S后H的顺序}//Train_Rearrange。
数据结构c语言版严蔚敏习题答案
数据结构c语言版严蔚敏习题答案数据结构是计算机科学中非常重要的一门课程,它研究的是数据的组织、存储和管理方式。
而C语言是一种被广泛应用于系统编程和嵌入式开发的编程语言。
在学习数据结构的过程中,很多人会选择使用严蔚敏编写的《数据结构(C语言版)》一书。
本文将针对该书中的习题,为大家提供一些答案和解析。
1. 顺序表顺序表是一种使用连续的内存空间来存储数据的数据结构。
在《数据结构(C语言版)》一书中,我们可以通过使用结构体来实现顺序表。
下面是一个示例代码:```c#include <stdio.h>#include <stdlib.h>#define MAXSIZE 100typedef struct {int data[MAXSIZE];int length;} SqList;void InitList(SqList *L) {L->length = 0;}void Insert(SqList *L, int pos, int value) {if (L->length >= MAXSIZE) {printf("顺序表已满,无法插入!"); return;}if (pos < 1 || pos > L->length + 1) { printf("插入位置非法!");return;}for (int i = L->length; i >= pos; i--) { L->data[i] = L->data[i - 1];}L->data[pos - 1] = value;L->length++;}void Delete(SqList *L, int pos) {if (pos < 1 || pos > L->length) {printf("删除位置非法!");return;}for (int i = pos - 1; i < L->length - 1; i++) { L->data[i] = L->data[i + 1];}L->length--;}int main() {SqList L;InitList(&L);Insert(&L, 1, 10);Insert(&L, 2, 20);Insert(&L, 3, 30);Delete(&L, 2);for (int i = 0; i < L.length; i++) {printf("%d ", L.data[i]);}return 0;}2. 链表链表是一种使用非连续的内存空间来存储数据的数据结构。
数据结构_(严蔚敏C语言版)_学习、复习提纲.
期末复习 第一章 绪论 复习1、计算机算法必须具备输入、输出、可行性、确定性、有穷性5个特性。
2、算法分析的两个主要方面是空间复杂度和时间复杂度。
3、数据元素是数据的基本单位。
4、数据项是数据的最小单位。
5、数据结构是带结构的数据元素的集合。
6、数据的存储结构包括顺序、链接、散列和索引四种基本类型。
基础知识数据结构算 法概 念逻辑结构 存储结构数据运算数据:计算机处理的信息总称 数据项:最小单位 数据元素:最基本单位数据对象:元素集合数据结构:相互之间存在一种或多种特定关系的数据元素集合。
概念:数据元素之间的关系 线性结构:一对一非线性结构 树:一对多 图:多对多顺序存储结构 链表存储结构 索引。
散列。
算法描述:指令的有限有序序列算法特性 有穷性 确定性 可行性 输入 输出 算法分析时间复杂度 空间复杂度第二章 线性表 复习1、在双链表中,每个结点有两个指针域,包括一个指向前驱结点的指针 、一个指向后继结点的指针2、线性表采用顺序存储,必须占用一片连续的存储单元3、线性表采用链式存储,便于进行插入和删除操作4、线性表采用顺序存储和链式存储优缺点比较。
5、简单算法第三章 栈和队列 复习线性表顺序存储结构链表存储结构概 念基本特点基本运算定义逻辑关系:前趋 后继节省空间 随机存取 插、删效率低 插入 删除单链表双向 链表 特点一个指针域+一个数据域 多占空间 查找费时 插、删效率高 无法查找前趋结点运算特点:单链表+前趋指针域运算插入删除循环 链表特点:单链表的尾结点指针指向附加头结点。
运算:联接1、 栈和队列的异同点。
2、 栈和队列的基本运算3、 出栈和出队4、 基本运算第四章 串 复习栈存储结构栈的概念:在一端操作的线性表 运算算法栈的特点:先进后出 LIFO初始化 进栈push 出栈pop队列顺序队列 循环队列队列概念:在两端操作的线性表 假溢出链队列队列特点:先进先出 FIFO基本运算顺序:链队:队空:front=rear队满:front=(rear+1)%MAXSIZE队空:frontrear ∧初始化 判空 进队 出队取队首元素第五章 数组和广义表 复习串存储结构运 算概 念顺序串链表串定义:由n(≥1)个字符组成的有限序列 S=”c 1c 2c 3 ……cn ”串长度、空白串、空串。
严蔚敏数据结构题集(C语言版)完整与答案
严蔚敏 数据结构C 语言版答案详解第1章 绪论1.1 简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。
解:数据是对客观事物的符号表示。
在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
数据对象是性质相同的数据元素的集合,是数据的一个子集。
数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
存储结构是数据结构在计算机中的表示。
数据类型是一个值的集合和定义在这个值集上的一组操作的总称。
抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。
是对一般数据类型的扩展。
1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。
解:抽象数据类型包含一般数据类型的概念,但含义比一般数据类型更广、更抽象。
一般数据类型由具体语言系统内部定义,直接提供给编程者定义用户数据,因此称它们为预定义数据类型。
抽象数据类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所进行的操作。
在定义抽象数据类型中的数据部分和操作部分时,要求只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接口。
1.3 设有数据结构(D,R),其中{}4,3,2,1d d d d D =,{}r R =,()()(){}4,3,3,2,2,1d d d d d d r =试按图论中图的画法惯例画出其逻辑结构图。
解:1.4 试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。
解:ADT Complex{ 数据对象:D={r,i|r,i 为实数} 数据关系:R={<r,i>} 基本操作: InitComplex(&C,re,im)操作结果:构造一个复数C ,其实部和虚部分别为re 和im DestroyCmoplex(&C)操作结果:销毁复数C Get(C,k,&e)操作结果:用e 返回复数C 的第k 元的值Put(&C,k,e)操作结果:改变复数C的第k元的值为eIsAscending(C)操作结果:如果复数C的两个元素按升序排列,则返回1,否则返回0 IsDescending(C)操作结果:如果复数C的两个元素按降序排列,则返回1,否则返回0 Max(C,&e)操作结果:用e返回复数C的两个元素中值较大的一个Min(C,&e)操作结果:用e返回复数C的两个元素中值较小的一个}ADT ComplexADT RationalNumber{数据对象:D={s,m|s,m为自然数,且m不为0}数据关系:R={<s,m>}基本操作:InitRationalNumber(&R,s,m)操作结果:构造一个有理数R,其分子和分母分别为s和mDestroyRationalNumber(&R)操作结果:销毁有理数RGet(R,k,&e)操作结果:用e返回有理数R的第k元的值Put(&R,k,e)操作结果:改变有理数R的第k元的值为eIsAscending(R)操作结果:若有理数R的两个元素按升序排列,则返回1,否则返回0 IsDescending(R)操作结果:若有理数R的两个元素按降序排列,则返回1,否则返回0 Max(R,&e)操作结果:用e返回有理数R的两个元素中值较大的一个Min(R,&e)操作结果:用e返回有理数R的两个元素中值较小的一个}ADT RationalNumber1.5 试画出与下列程序段等价的框图。
数据结构C语言版第版习题答案—严蔚敏精修订
数据结构C语言版第版习题答案—严蔚敏GE GROUP system office room 【GEIHUA16H-GEIHUA GEIHUA8Q8-数据结构(C语言版)(第2版)课后习题答案李冬梅2015.3目录第1章绪论............................................. 第2章线性表 ........................................... 第3章栈和队列 ......................................... 第4章串、数组和广义表.................................. 第5章树和二叉树 ....................................... 第6章图................................................ 第7章查找 ............................................. 第8章排序.............................................第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。
如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。
数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
在有些情况下,数据元素也称为元素、结点、记录等。
数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。
例如,学生基本信息表中的学号、姓名、性别等都是数据项。
chap003 栈和队列-数据结构(C语言版)-严蔚敏-清华大学出版社
例三、行编辑程序问题
如何实现?
“每接受一个字符即存入存储器” ?
并不恰当!
在用户输入一行的过程中,允许 用户输入出差错,并在发现有误时 可以及时更正。 合理的作法是:
设立一个输入缓冲区,用以接受 用户输入的一行字符,然后逐行存 入用户数据区,并假设“#”为退格 符,“@”为退行符。
GetTop(S, &e) 初始条件:栈 S 已存在且非空。 操作结果:用 e 返回 S 的栈顶
元素。
a1 a2 … … an
ClearStack(&S) 初始条件:栈 S 已存在。 操作结果:将 S 清为空栈。
Push(&S, e) 初始条件:栈 S 已存在。 操作结果:插入元素 e 为新
的栈顶元素。
分析可能出现的不匹配的情况:
• 到来的右括弧并非是所“期待” • 的到;来的是“不速之客”;
• 直到结束,也没有到来所“期待” 的括弧。
算法的设计思想:
1)凡出现左括弧,则进栈;
2)凡出现右括弧,首先检查栈是否空 若栈空,则表明该“右括弧”多余, 否则和栈顶元素比较, 若相匹配,则“左括弧出栈” , 否则表明不匹配。
} // conversion
例二、 括号匹配的检验 假设在表达式中 ([]())或[([ ][ ])] 等为正确的格式, [( ])或([( ))或 (()]) 均为不正确的格式。
则 检验括号是否匹配的方法可用 “期待的急迫程度”这个概念来描述。
例如:考虑下列括号序列: [( [ ][ ] )] 1 2 34 5 6 7 8
switch (ch) {
《数据结构(C语言版第2版)》(严蔚敏著)第三章练习题答案
《数据结构(C语言版第2版)》(严蔚敏著)第三章练习题答案《数据结构(C语言版第2版)》(严蔚敏著)第三章练习题答案第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答案:C解释:栈是后进先出的线性表,不难发现C选项中元素1比元素2先出栈,违背了栈的后进先出原则,所以不可能出现C选项所示的情况。
(2)若已知一个栈的入栈序列是1,2,3,…,n,其输出序列为p1,p2,p3,…,pn,若p1=n,则pi为()。
A.i B.n-i C.n-i+1 D.不确定答案:C解释:栈是后进先出的线性表,一个栈的入栈序列是1,2,3,…,n,而输出序列的第一个元素为n,说明1,2,3,…,n一次性全部进栈,再进行输出,所以p1=n,p2=n-1,…,pi=n-i+1。
(3)数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素个数的公式为()。
A.r-f B.(n+f-r)%n C.n+r-f D.(n+r-f)%n答案:D解释:对于非循环队列,尾指针和头指针的差值便是队列的长度,而对于循环队列,差值可能为负数,所以需要将差值加上MAXSIZE(本题为n),然后与MAXSIZE(本题为n)求余,即(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;答案:A解释:x=top->data将结点的值保存到x中,top=top->link栈顶指针指向栈顶下一结点,即摘除栈顶结点。
数据结构c语言版严蔚敏
在本门课程的学习、作业练习、上机实践等环节, 算法都用C语言来描述。在上机实践时,为了检查算法 是否正确,应编写成完整的C语言程序。
1.3.2 算法设计的要求
算法(Algorithm):是对特定问题求解方法(步骤)的一种 描述,是指令的有限序列,其中每一条指令表示一个或 多个操作。
算法具有以下五个特性
① 有穷性: 一个算法必须总是在执行有穷步之后结 束,且每一步都在有穷时间内完成。
② 确定性:算法中每一条指令必须有确切的含义。 不存在二义性。且算法只有一个入口和一个出口。
数据元素(Data Element) :是数据的基本单位,在 程序中通常作为一个整体来进行考虑和处理。
一个数据元素可由若干个数据项(Data Item)组成。 数据项是数据的不可分割的最小单位。数据项是对客观 事物某一方面特性的数据描述。
数据对象(Data Object):是性质相同的数据元素的集 合,是数据的一个子集。如字符集合C={‘A’,’B’,’C,…} 。
③ 可行性: 一个算法是能行的。即算法描述的操作 都可以通过已经实现的基本运算执行有限次来实现。
④ 输入: 一个算法有零个或多个输入,这些输入 取自于某个特定的对象集合。
⑤ 输出: 一个算法有一个或多个输出,这些输出 是同输入有着某些特定关系的量。
一个算法可以用多种方法描述,主要有:使用自然 语言描述;使用形式语言描述;使用计算机程序设计语 言描ct Data Type ,简称ADT):是 指一个数学模型以及定义在该模型上的一组操作。
ADT的定义仅是一组逻辑特性描述, 与其在计算 机内的表示和实现无关。因此,不论ADT的内部结构如 何变化,只要其数学特性不变,都不影响其外部使用。
数据结构c语言版严蔚敏课后习题答案
数据结构c语言版严蔚敏课后习题答案数据结构是计算机科学中非常重要的一门学科,它研究的是数据的组织、存储和管理方式。
而C语言作为一种广泛应用于系统编程和嵌入式开发的高级编程语言,与数据结构的学习息息相关。
本文将针对《数据结构(C语言版)》严蔚敏教材的课后习题提供一些答案,希望能够帮助读者更好地理解和掌握数据结构。
第一章:绪论在第一章中,主要介绍了数据结构的基本概念和基本术语。
课后习题主要是一些概念性的问题,例如数据结构与算法的关系、数据的逻辑结构和物理结构等。
这些问题的答案可以通过仔细阅读教材中的相关内容来得到。
第二章:线性表线性表是数据结构中最基本、最常用的一种结构。
课后习题主要涉及线性表的基本操作,如插入、删除、查找等。
这些问题的答案可以通过编写相应的C语言代码来实现。
第三章:栈和队列栈和队列是线性表的特殊形式,具有后进先出(LIFO)和先进先出(FIFO)的特点。
课后习题主要涉及栈和队列的基本操作,如进栈、出栈、入队、出队等。
这些问题的答案同样可以通过编写相应的C语言代码来实现。
第四章:串串是由零个或多个字符组成的有限序列,是一种特殊的线性表。
课后习题主要涉及串的模式匹配、串的替换等操作。
这些问题的答案可以通过使用C语言的字符串处理函数来实现。
第五章:数组和广义表数组是一种线性表的顺序存储结构,广义表是线性表的扩展。
课后习题主要涉及数组和广义表的创建、访问和操作等。
这些问题的答案可以通过编写相应的C语言代码来实现。
第六章:树树是一种非线性的数据结构,具有层次关系。
课后习题主要涉及树的遍历、节点的插入和删除等操作。
这些问题的答案可以通过使用C语言的指针和递归来实现。
第七章:图图是一种非线性的数据结构,由节点和边组成。
课后习题主要涉及图的遍历、最短路径、最小生成树等操作。
这些问题的答案可以通过使用C语言的图算法来实现。
通过以上的简要介绍,读者可以了解到《数据结构(C语言版)》严蔚敏教材的课后习题主要涵盖了线性表、栈和队列、串、数组和广义表、树、图等各个方面。
数据结构实用教程(C语言版) 第3章 栈和队列
3.1.1 栈的概念
假设有一个栈S=(a1,a2,…,an),栈 中元素按a1,a2,…,an的次序进栈后, 进栈的第一个元素a1为栈底元素,出栈的第 一个元素an为栈顶元素,也就是出栈的操作 是按后进先出的原则进行的,其结构如图31所示。
图3-1栈结构示意图
返回到本节目录
3.1.2栈的基本操作
3.1.3顺序栈
由于栈是操作受限制的线性表,因此与线性表类似,栈也 有两种存储结构,即顺序存储结构和链式存储结构。 1. 顺序栈的定义 栈的顺序存储结构称为顺序栈。类似于顺序表的类型定义,顺 序栈是用一个预设的足够长度的一维数组和一个记录栈顶元素 位置的变量来实现。顺序栈中栈顶指针与栈中数据元素的关1.3顺序栈
3. 顺序栈的基本操作实现
(3)进栈操作 进栈操作的过程如图3-3所示。先判断栈S如图3-3(a) 是否为满,若不满再将记录栈顶的下标变量top加1如 图3-3(b),最后将进栈元素放进栈顶位置上如图33(c)所示,算法描述见算法3.3。
图3-3 进栈操作过程图
返回到本节目录
栈除了在栈顶进行进栈与出栈外,还有初始化、判空 等操作,常用的基本操作有: (1)初始化栈InitStack(S)。其作用是构造一个空 栈 S。 (2)判断栈空EmptyStack(S)。其作用是判断是 否是空栈,若栈S为空,则返回1;否则返回0。 (3)进栈Push(S,x)。其作用是当栈不为满时,将 数据元素x插入栈S中,使其为栈S的栈顶元素。 (4)出栈Pop(S,x)。其作用是当栈S不为空时,将 栈顶元素赋给x,并从栈S中删除当前栈顶元素。 (5)取栈顶元素GetTop(S,x)。其作用是当栈S不 为空时,将栈顶元素赋给x并返回,操作结果只是 读取栈顶元素,栈S不发生变化。 返回到本节目录
数据结构C语言版(第2版)严蔚敏人民邮电出版社课后习题答案
数据结构( C语言版)(第 2版)课后习题答案李冬梅2015.3目录第 1 章绪论 (1)第 2 章线性表 (5)第 3 章栈和队列 (13)第 4 章串、数组和广义表 (26)第 5 章树和二叉树 (33)第 6 章图 (43)第 7 章查找 (54)第 8 章排序 (65)第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。
如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。
数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
在有些情况下,数据元素也称为元素、结点、记录等。
数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。
例如,学生基本信息表中的学号、姓名、性别等都是数据项。
数据对象:是性质相同的数据元素的集合,是数据的一个子集。
例如:整数数据对象是集合N={0 ,± 1,± 2,, } ,字母字符数据对象是集合C={‘A’,‘B’, , ,‘Z’,‘ a’,‘ b’, , ,‘z ’} ,学生基本信息表也可是一个数据对象。
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。
换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。
逻辑结构:从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。
因此,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。
存储结构:数据对象在计算机中的存储表示,也称为物理结构。
抽象数据类型:由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。
具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。
数据结构 C语言版(严蔚敏版)第3章 栈和队列
if (S.top == S.base) return FALSE; --S.top; // 栈顶指针前移 e = *S.top; // 返回非空栈中栈顶元
素
return TRUE; }
4. {
获取栈顶元素内容
bool GetTop (Stack S, ElemType &e)
// 若栈不空,则用 e 返回S的栈顶元素,并返回TRUE;否 则返回FALSE
第3章 栈和队列
栈和队列是两种特殊的线性表,它们是运算 时要受到某些限制的线性表,故也称为限定性的 数据结构。
3.1 栈
3.1.1栈的定义
栈:限定只能在表的一端进行插入和删除的特殊的线性表 设栈s=(a1,a2,. . . ,ai,. . . ,an), 其中a1是栈底元素, an是栈顶元素。 进栈 出栈 an „. a2
10
65
865
第3章 栈和队列
学习提要
1.掌握栈和队列这两种抽象数据类型的特点, 并能在相应的应用问题中正确选用它们。 2. 熟练掌握栈类型的两种实现方法,即两种 存储结构表示时的基本操作实现算法,特别应 注意栈满和栈空的条件以及它们的描述方法。
3. 熟练掌握循环队列和链队列的基本操作实 现算法,特别注意队满和队空的描述方法。
4.
获取栈顶元素内容
void GetTop(STACK S,StackEntry *item)
{
if (StackEmpty(S)) exit(“Stack is empty”); else *item=S.top->item; }
5. {
判断栈S是否空
int StackEmpty(STACK S) if (S.top==NULL) return TRUE;
数据结构(C语言版)严蔚敏清华大学出版社第三章栈和队列
压入(PUSH): S[top++]=an 弹出( POP) : e=S[--top]
前提:一定要预设栈顶指针top
top 空栈
top
e d c b a
e 进栈
top top
a
a 进栈
top
e
top
d
c
b a
f 进栈溢出
b a b 进栈
e d c b a e 退栈
top d c b a
d 退栈
top c b a
{ LSNode *p;
if((p = (LSNode *)malloc(sizeof(LSNode))) == NULL) { printf("内存空间不足无法插入! \n");
return 0;
}
p->data = x; p->next = head->next; head->next = p;
#define STACKINCREMENT 10
Typedef struct{ datatype *base, *top; int stacksize;
} SqStack;
数据结构
第十一讲
栈的链式实现及栈的应用(1)
主讲:刘立嘉
1、 栈的链式表示和实现
栈也可以用链式结构来表示,用链式结构来表示的栈就是链栈 1、 链栈的存储结构 以头结点为栈顶,在头结点处插入或删除.
从栈顶删除最后一 个元素的操作,称 为出栈。
注:堆栈可以完成比较复杂的数据元素特定序列 的转换任务,但它不能完成任何输入输出序列的 转换任务。
例1:堆栈是什么?它与一般线性表有什么不同?
堆栈是一种特殊的线性表,它只能在表的一端(即 栈顶)进行插入和删除运算。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.2.1 栈的顺序存储结构及实现 两栈共享空间
0 1 2 ……
S-1
a1 a 2 … ai
top1
top1
bj … … b2 b1
top2 top1= -1
什么时候栈1为空?
3.2.1 栈的顺序存储结构及实现 两栈共享空间
0 1 2 ……
S-1
a 1 a2 … ai
top1
什么时候栈1为空? 什么时候栈2为空?
栈的顺序存储结构简称为顺序栈,它是运算受限 的线性表。因此,可用数组来实现顺序栈。因为栈底 位置是固定不变的,所以可以将栈底位置设置在数组 的两端的任何一个端点;栈顶位置是随着进栈和退栈 操作而变化的,故需用一个整型变量top
定义:利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元 素,同时附设指针top指示栈顶元素在顺序栈中的位置。
(4)取栈顶元素操作 取出栈顶元素:先判断栈是否为空,不为 空,则将栈顶元素值取出。 出栈和取栈顶值是不同的。
3.2.1 栈的顺序存储结构及实现 (5)判栈空操作
看栈顶和栈底是否相等。 (6)置空操作 栈顶和栈底相等
3.2.1 栈的顺序存储结构及实现 两栈共享空间
在一个程序中需要同时使用具有相同数据类型的 两个栈,如何顺序存储这两个栈? 解决方案1:
3.2.2 栈的链式存储结构及实现
链栈:栈的链接存储结构 如何改造链表实现栈的链接存储?
head
a1
a2
an
将哪一端作为栈顶? 将链头作为栈顶,方便操作。 链栈需要加头结点吗? 链栈不需要附设头结点。
栈的链式存储结构称为链栈,它是运算是受限的单链表,插入和删除操作仅限制在表 头位置上进行.由于只能在链表头部进行操作,故链表没有必要像单链表那样附加头 结点。栈顶指针就是链表的头指针。
an
an-1
p
ls
a1 ∧
a1 ∧
3.2.3 栈的存储结构的比较 顺序栈和链栈的比较
时间性能:相同,都是常数时间O(1)。 空间性能: 顺序栈:有元素个数的限制和空间浪费的问题。 链栈:没有栈满的问题,只有当内存没有可用空 间时才会出现满的情况,但是每个元素都需要一个 指针域,从而产生了结构性开销。 总之,当栈的使用过程中元素个数变化较大时,用 链栈是适宜的,反之,应该采用顺序栈。
n 1348 168 21 2
n div 8 168 21 2 0
n mod 8 4 0 5 2
数制转换
n 1348 168 21 2
n div 8 168 21 2 0
n mod 8 4 0 5 2
2 5 0 4
栈顶
栈底
程序
void conversion( ) { initstack(s); scanf (“%”,n); while(n){ push(s,n%8); n=n/8; } while(! Stackempty(s)){ pop(s,e); printf(“%d”,e); } }
3.2.1 栈的顺序存储结构及实现 两栈共享空间
0 1 2 ……
S-1
a1 a2 … ai
栈1底
bj … … b2 b1
top2
栈2底
top1
栈1的底固定在下标为0的一端; 栈2的底固定在下标为StackSize-1的一端。 top1和top2分别为栈1和栈2的栈顶指示器; Stack_Size为整个数组空间的大小(图中用S表示);
3.1 栈的逻辑结构
注意: 栈只是对表插入和删除操作的位置进行了 限制,并没有限定插入和删除操作进行的 时间。 思考: 有三个元素按a、b、c的次序依次进栈, 且每个元素只允许进一次栈,则可能的出栈 序列有多少种?
3.2.1 栈的顺序存储结构及实现
由于栈是运算受限的线性表,因此线性表的存储结构对栈也适应。 顺序存储结构
3.2.1 栈的顺序存储结构及实现
“上溢”-----当s.top =stacksize-1表示栈满,此时, 再做进栈运算必定产生空间溢出,简称“上溢” “下溢”-----当s.top=s.base(或s.top=-1)时表示栈空, 此时再做退栈运算也将产生溢出,简称“下溢”。
上溢是一种出错状态,应该设法避免之;下溢则可能 是正常现象,因为栈在程序中使用时,其初态或终态 都是空栈,所以下溢常常用来作为程序控制转移的条 件。
3.3 栈的应用
由于栈结构具有后进先出的固有特性,致使栈成为程 序设计中常用的工具。以下是几个栈应用的例子。
3.3栈的应用举例
3.3.1 数制转换 十进制N和其它进制数的转换是计算机实现计算的基本 问题,其解决方法很多,其中一个简单算法基于下列原理: N=(n div d)*d+n mod d ( 其中:div为整除运算,mod为求余运算) 例如 (1348)10=(2504)8,其运算过程如下:
队列(Queue)也是一种运算受限的线性表。它只允 许在表的一端进行插入,而在另一端进行删除。 允许删除的一端称为队头(front),允许插入的 一端称为队尾(rear)。 例如:排队购物。操作系统中的作业排队。先 进入队列的成员总是先离开队列。因此队列亦称 作先进先出(First In First Out)的线性表,简 称FIFO表。 当队列中没有元素时称为空队列。在空队列中 依次加入元素a1,a2,…an之后,a1是队头元素,an 是队尾元素。显然退出队列的次序也只能是 a1,a2,…an ,也就是说队列的修改是依先进先出op
an a n-1
(a1, a2, ……, an)
……
a2
栈底base
a1
栈的示意图
3.1 栈的逻辑结构
入栈
则
设栈S=( a1 a1, a2, ……, an),
a1为栈底元素, an为栈顶元
栈顶top
an a n-1
出栈 素
……
a2
空栈:不含任何数据元 素的栈。 插入:入栈、进栈、压栈
直接解决:为每个栈开辟一个数组空间。 会出现什么问题?如何解决?
解决方案2:
顺序栈单向延伸——使用一个数组来存储两个栈
3.2.1 栈的顺序存储结构及实现 两栈共享空间
两栈共享空间:使用一个数组来存储两个栈,让一个 栈的栈底为该数组的始端,另一个栈的栈底为该数组 的末端,两个栈从各自的端点向中间延伸。
链表存储结构
3.2.1 栈的顺序存储结构及实现
顺序栈——栈的顺序存储结构
如何改造数组实现栈的顺序存储?
0 1 2 3 4 5 6 7 8
a1
top 确定用数组的哪一端表示栈底。 附设指示器top指示栈顶元素在数组中的位置。
3.2.1 栈的顺序存储结构及实现
栈中元素与栈顶指针的变化:
top
4 3 2
bj … … b2 b 1
top2
top1= -1 top2
top2= Stack_Size
3.2.1 栈的顺序存储结构及实现 两栈共享空间
0 1 2 ……
S-1
a1 a2 … … ai bj
top1 top2 什么时候栈1为空? 什么时候栈2为空? 什么时候栈满?
…
… b2 b1
top1= -1 top2= Stack_Size top2= top1+1
765 432 1
入栈
top
-1
3.2.1 栈的顺序存储结构及实现
顺序栈的实现
(1)初始化栈 建立一个空栈,栈顶和栈底相同。给出最大 空间大小 (2)入栈操作 入栈操作:将元素插入,作为新栈顶,top指针+1.
3.2.1 栈的顺序存储结构及实现
(3)出栈操作
出栈操作:判断栈S是否为空,不为空, 则 top 指针下移 1 为 , 将栈顶元素复制给 X 取出。
3.5.1 队列的链式存储结构 3.5.2 队列的顺序存储结构
第三章 栈和队列
从数据结构角度看,栈和队列是操作受限 的线性表,他们的逻辑结构相同。 栈只允许在表的一端进行插入或删除操 作 队列只允许在表的一端进行插入操作、 而在另一端进行删除操作。
3.1 栈的逻辑结构 1.栈的定义
栈:限定仅在表尾进行插入和删除操作的线性表。 允许插入和删除的一端称为栈顶,另一个固定 端称为栈底。
3.5.1队列的链式存储结构及实现
1、队列的链队列
链队列:队列的链式存储结构
如何改造单链表实现队列的链式存储?
head front 队头指针即为链表的头指针 链队列是否需要附设头结点吗?
a1
a2
rear
an
链队列
队列的链式存储结构简称为链队列,它是限制仅在表头 删除和表尾插入的单链表。显然仅有单链表的头指针不 便于在表尾做插入操作,为此再增加一个尾指针,指向 链表的最后一个结点。于是,一个链队列由一个头指针 唯一确定。和顺序队列类似,我们也是将这两个指针封 装在一起,将链队列的类型LinkQueue定义为一个结构类 型:
3.2.2 栈的链式存储结构及实现
链栈:栈的链接存储结构 head
a1
an-1
a2
a1
∧
an top
an an-1
top
an
栈顶
栈底
栈顶
data next
结点结构
两种示意图在内存中 对应同一种状态
a1
∧
栈底
3.2.2 栈的链式存储结构及实现 链栈中数据元素与栈顶指针top的关系:
top top C B
B A
∧
( a)
A
∧
top
A (c)
∧
( b)
(a)栈空 top=null (b)含有两个元素A、B的栈; (c)插入元素C后的栈; (d)删除元素C、B后的栈
3.2.2 栈的链式存储结构及实现 链栈的类型说明如下: typedef struct snode{ elemtype data; struct snode *next; }StackNode,*LkStack;