数据结构栈和队列精品文稿.ppt
《数据结构栈和队列精品文稿.ppt》由会员分享,可在线阅读,更多相关《数据结构栈和队列精品文稿.ppt(54页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、数据结构栈和队列第1页,本讲稿共54页3.1 栈栈3.1.1 栈的基本概念栈的基本概念1 栈的概念栈的概念 栈栈(Stack):是限制在表的一端进行插入和删除操作是限制在表的一端进行插入和删除操作的线性表。又称为后进先出的线性表。又称为后进先出LIFO(Last In First Out)或先进后或先进后出出FILO(First In Last Out)线性线性表。表。栈顶栈顶(Top):允许进行插入、删除操作的一端,又允许进行插入、删除操作的一端,又称为表尾。用栈顶指针称为表尾。用栈顶指针(top)来指示栈顶元素来指示栈顶元素。栈底栈底(Bottom):是固定端,又称为表头。是固定端,又称为
2、表头。空栈空栈:当表中没有元素时称为空栈。当表中没有元素时称为空栈。第2页,本讲稿共54页 设栈设栈S=(a1,a2,an),则,则a1称为栈称为栈底元素,底元素,an为栈顶元素,如图为栈顶元素,如图3-1所示。所示。栈中元素按栈中元素按a1,a2,an的次序进栈,的次序进栈,退栈的第一个元素应为栈顶元素。即栈的退栈的第一个元素应为栈顶元素。即栈的修改是按后进先出的原则进行的。修改是按后进先出的原则进行的。图图3-1 顺序顺序栈示意图栈示意图a1a2aianbottomtop进栈(进栈(push)出栈出栈(pop)2 栈的抽象数据类型定义栈的抽象数据类型定义ADT Stack数据对象:数据对象
3、:D=ai|aiElemSet,i=1,2,n,n0 数据关系:数据关系:R=|ai-1,aiD,i=2,3,n 基本操作:初始化、进栈、出栈、取栈顶元素等基本操作:初始化、进栈、出栈、取栈顶元素等 ADT Stack第3页,本讲稿共54页 栈的顺序存储结构简称为顺序栈,和线性表相类似,栈的顺序存储结构简称为顺序栈,和线性表相类似,用用一维数组一维数组来来存储栈存储栈。根据数组是否可以根据需要增大,。根据数组是否可以根据需要增大,又可分为又可分为静态顺序栈静态顺序栈和和动态顺序栈动态顺序栈。静态顺序栈静态顺序栈实现简单,但不能根据需要增大栈的实现简单,但不能根据需要增大栈的存储空间;存储空间;
4、动态顺序栈动态顺序栈可以根据需要增大栈的存储空间,但可以根据需要增大栈的存储空间,但实现稍为复杂。实现稍为复杂。3.1.2 栈的顺序存储表示栈的顺序存储表示第4页,本讲稿共54页 采用采用动态动态一维数组一维数组来来存储栈存储栈。所谓动态,指的是栈的大。所谓动态,指的是栈的大小可以根据需要增加。小可以根据需要增加。用用bottom表示栈底指针,栈底固定不变的;栈顶表示栈底指针,栈底固定不变的;栈顶则随着进栈和退栈操作而变化。用则随着进栈和退栈操作而变化。用top(称为栈顶指针称为栈顶指针)指示当前栈顶位置。指示当前栈顶位置。用用top=bottom作为栈空的标记作为栈空的标记,每次,每次top
5、指向栈顶指向栈顶数组中的下一个存储位置。数组中的下一个存储位置。结点进栈结点进栈:首先将数据元素保存到栈顶首先将数据元素保存到栈顶(top所指所指的当前位置的当前位置),然后执行,然后执行top加加1,使,使top指向栈顶的下指向栈顶的下一个存储位置一个存储位置;3.1.2.1 栈的动态顺序存储表示栈的动态顺序存储表示第5页,本讲稿共54页 结点出栈结点出栈:首先执行:首先执行top减减1,使,使top指向栈顶元素指向栈顶元素的存储位置,然后将栈顶元素取出的存储位置,然后将栈顶元素取出。图图3-2是一个动态栈的变化示意图是一个动态栈的变化示意图。图图3-2 (动态动态)堆栈变化示意图堆栈变化示
6、意图空栈空栈bottomtop元素元素a进栈进栈bottomtopa元素元素b,c进栈进栈bottomtopabc元素元素c退栈退栈bottomtopabbottomtopabdef元素元素d,e,f进栈进栈第6页,本讲稿共54页基本操作的实现基本操作的实现1 栈的类型定义栈的类型定义#define STACK_SIZE 100 /*栈初始向量大小栈初始向量大小 */#define STACKINCREMENT 10 /*存储空间分配增量存储空间分配增量 */#typedef int ElemType;typedef struct sqstack ElemType *bottom;/*栈不存在
7、时值为栈不存在时值为NULL */ElemType *top;/*栈顶指针栈顶指针 */int stacksize;/*当前已分配空间,以元素为单位当前已分配空间,以元素为单位 */SqStack;第7页,本讲稿共54页2 栈的初始化栈的初始化Status Init_Stack(void)SqStack S;S.bottom=(ElemType*)malloc(STACK_SIZE*sizeof(ElemType);if(!S.bottom)return ERROR;S.top=S.bottom;/*栈空时栈顶和栈底指针相同栈空时栈顶和栈底指针相同 */S.stacksize=STACK_SI
8、ZE;return OK;第8页,本讲稿共54页3 压栈压栈(元素进栈元素进栈)Status push(SqStack S,ElemType e)if (S.top-S.bottom=S.stacksize-1)S.bottom=(ElemType*)realloc(S.STACKINCREMENT+STACK_SIZE)*sizeof(ElemType);/*栈满,追加存储空间栈满,追加存储空间 */if(!S.bottom)return ERROR;S.top=S.bottom+S.stacksize;S.stacksize+=STACKINCREMENT;*S.top=e;S.top+;
9、/*/*栈顶指针加栈顶指针加1,e成为新的栈顶成为新的栈顶*/*/return OK;第9页,本讲稿共54页4 弹栈弹栈(元素元素出栈出栈)Status pop(SqStack S,ElemType *e)/*弹出栈顶元素弹出栈顶元素*/if(S.top=S.bottom)return ERROR;/*栈空,返回失败标志栈空,返回失败标志 */S.top-;e=*S.top;return OK;第10页,本讲稿共54页 采用采用静态静态一维数组一维数组来来存储栈存储栈。栈底固定不变的,而栈顶则随着进栈和退栈操作变化的,栈底固定不变的,而栈顶则随着进栈和退栈操作变化的,栈底固定不变的;栈顶则随着
10、进栈和退栈操作而栈底固定不变的;栈顶则随着进栈和退栈操作而变化,用一个整型变量变化,用一个整型变量top(称为栈顶指针称为栈顶指针)来指示当前来指示当前栈顶位置。栈顶位置。用用top=0表示栈空的初始状态表示栈空的初始状态,每次,每次top指向栈顶指向栈顶在数组中的存储位置在数组中的存储位置。结点进栈结点进栈:首先执行首先执行top加加1,使,使top指向新的栈顶指向新的栈顶位置位置,然后将数据元素保存到栈顶然后将数据元素保存到栈顶(top所指的当前位所指的当前位置置)。3.1.2.2 栈的静态顺序存储表示栈的静态顺序存储表示(简略简略)第11页,本讲稿共54页 结点出栈结点出栈:首先首先把把
11、top指向的栈顶元素取出指向的栈顶元素取出,然后然后执行执行top减减1,使,使top指向新的栈顶位置指向新的栈顶位置。若栈的数组有若栈的数组有Maxsize个元素个元素,则,则top=Maxsize-1时栈满时栈满。图图3-3是一个大小为是一个大小为5的栈的变化示意图的栈的变化示意图。图图3-3 静态静态堆栈变化示意图堆栈变化示意图空栈空栈bottomtopTop=11个元素进栈个元素进栈bottomtopaTop=33个元素进栈个元素进栈bottomtopabcTop=4栈满栈满bottomtopabedTop=2元素元素c进栈进栈bottomtopab第12页,本讲稿共54页基本操作的实
12、现基本操作的实现1 栈的类型定义栈的类型定义#define MAX_STACK_SIZE 100 /*栈向量大小栈向量大小 */#typedef int ElemType;typedef struct sqstack ElemType stack_arrayMAX_STACK_SIZE;int top;SqStack;第13页,本讲稿共54页2 栈的初始化栈的初始化SqStack Init_Stack(void)SqStack S;S.bottom=S.top=0;return(S);第14页,本讲稿共54页3 压栈压栈(元素进栈元素进栈)Status push(SqStack S,ElemT
13、ype e)/*/*使数据元素使数据元素e进栈成为新的栈顶进栈成为新的栈顶 */*/if (S.top=MAX_STACK_SIZE-1)return ERROR;/*栈满,返回错误标志栈满,返回错误标志 */S.top+;/*/*栈顶指针加栈顶指针加1 */*/S.stack_arrayS.top=e ;/*/*e成为新的栈顶成为新的栈顶 */*/return OK;/*压栈成功压栈成功 */第15页,本讲稿共54页4 弹栈弹栈(元素元素出栈出栈)Status pop(SqStack S,ElemType *e)/*弹出栈顶元素弹出栈顶元素*/if(S.top=0)return ERROR;
14、/*栈空,返回错误标志栈空,返回错误标志 */*e=S.stack_arrayS.top;S.top-;return OK;第16页,本讲稿共54页 当栈满时做进栈运算必定产生空间溢出,简称当栈满时做进栈运算必定产生空间溢出,简称“上溢上溢”。上溢是一种出错状态,应设法避免。上溢是一种出错状态,应设法避免。当栈空时做退栈运算也将产生溢出,简称当栈空时做退栈运算也将产生溢出,简称“下溢下溢”。下溢则可能是正常现象,因为栈在使用时,其初态或终态下溢则可能是正常现象,因为栈在使用时,其初态或终态都是空栈,所以下溢常用来作为控制转移的条件。都是空栈,所以下溢常用来作为控制转移的条件。第17页,本讲稿共
15、54页1 栈的链式表示栈的链式表示 栈的栈的链式存储结构链式存储结构称为链栈,是运算受限的单链表。其称为链栈,是运算受限的单链表。其插入和删除操作只能在表头位置上进行。因此,链栈没有必要插入和删除操作只能在表头位置上进行。因此,链栈没有必要像单链表那样附加头结点,栈顶指针像单链表那样附加头结点,栈顶指针top就是链表的头指针。图就是链表的头指针。图3-4是栈的链式存储表示形式是栈的链式存储表示形式。3.1.3 栈的链式存储表示栈的链式存储表示(简略简略)空栈空栈top 非空栈非空栈top a4 a3 a1 a2图图图图3-4 3-4 链链链链栈存储形式栈存储形式链栈的链栈的结点类型说明如下:结
16、点类型说明如下:typedef struct Stack_Node ElemType data;struct Stack_Node *next;Stack_Node;第18页,本讲稿共54页2 链栈基本操作的实现链栈基本操作的实现(1)栈的初始化栈的初始化Stack_Node *Init_Link_Stack(void)Stack_Node *top;top=(Stack_Node *)malloc(sizeof(Stack_Node);top-next=NULL;return(top);第19页,本讲稿共54页(2)压栈压栈(元素进栈元素进栈)Status push(Stack_Node*t
17、op,ElemType e)Stack_Node *p;p=(Stack_Node *)malloc(sizeof(Stack_Node);if(!p)return ERROR;/*申请新结点失败,返回错误标志申请新结点失败,返回错误标志*/p-data=e;p-next=top-next ;top-next=p;/*钩链钩链 */return OK;第20页,本讲稿共54页(3)弹栈弹栈(元素元素出栈出栈)Status pop(Stack_Node *top,ElemType*e)/*/*将栈顶元素将栈顶元素出出栈栈 */*/Stack_Node *p;ElemType e;if (top-
18、next=NULL)return ERROR;/*栈空,返回错误标志栈空,返回错误标志 */p=top-next;e=p-data;/*/*取栈顶元素取栈顶元素 */*/top-next=p-next;/*/*修改栈顶指针修改栈顶指针 */*/free(p);return OK;第21页,本讲稿共54页3.2 栈的应用栈的应用 由于栈具有的由于栈具有的“后进先出后进先出”的固有特性,因此,栈成为的固有特性,因此,栈成为程序设计中常用的工具和数据结构。以下是几个栈应用的例程序设计中常用的工具和数据结构。以下是几个栈应用的例子。子。第22页,本讲稿共54页3.2.1 数制转换数制转换十进制整数十进
19、制整数N向其它进制数向其它进制数d(二二、八八、十六十六)的转换是计算机实现的转换是计算机实现计算的基本问题。计算的基本问题。转换法则转换法则:该转换法则对应于一个简单算法原理该转换法则对应于一个简单算法原理:n=(n div d)*d+n mod d 其中:其中:div为整除运算为整除运算,mod为求余运算为求余运算例如例如 (1348)10=(2504)8,其运算过程如下:其运算过程如下:n n div 8 n mod 8 1348 168 4 168 21 0 21 2 5 2 0 2第23页,本讲稿共54页 采用静态顺序栈方式实现采用静态顺序栈方式实现 void conversion(
20、int n,int d)/*将将十进制整数十进制整数N转换为转换为d(2或或8)进制数进制数*/SqStack S;int k,*e;S=Init_Stack();while (n0)k=n%d;push(S,k);n=n/d;/*求出所有的余求出所有的余数,数,进栈进栈 */while (S.top!=0)/*栈不空时出栈,输出栈不空时出栈,输出 */pop(S,e);printf(“%1d”,*e);第24页,本讲稿共54页3.2.2 括号匹配问题括号匹配问题 在文字处理软件或编译程序设计时,常常需要检查一个字符在文字处理软件或编译程序设计时,常常需要检查一个字符串或一个表达式中的括号是否
21、相匹配串或一个表达式中的括号是否相匹配?匹配思想匹配思想:从左至右扫描一个字符串从左至右扫描一个字符串(或表达式或表达式),则,则每每个右括号将与最近遇到的那个左括号相匹配个右括号将与最近遇到的那个左括号相匹配。则可以在从。则可以在从左至右扫描过程中把所遇到的左括号存放到堆栈中。每当遇到一左至右扫描过程中把所遇到的左括号存放到堆栈中。每当遇到一个右括号时,就将它与栈顶的左括号个右括号时,就将它与栈顶的左括号(如果存在如果存在)相匹配,同时从相匹配,同时从栈顶删除该左括号。栈顶删除该左括号。算法思想算法思想:设置一个栈,当读到左括号时,左括号进栈。当设置一个栈,当读到左括号时,左括号进栈。当读到
22、右括号时,则从栈中弹出一个元素,与读到的左括号进行匹读到右括号时,则从栈中弹出一个元素,与读到的左括号进行匹配,若匹配成功,继续读入;否则匹配失败,返回配,若匹配成功,继续读入;否则匹配失败,返回FLASE。第25页,本讲稿共54页算法描述算法描述#define TRUE 0#define FLASE -1SqStack S;S=Init_Stack();/*堆栈初始化堆栈初始化*/int Match_Brackets()char ch,x;scanf(“%c”,&ch);while(asc(ch)!=13)/*不等于回车不等于回车*/第26页,本讲稿共54页 if (ch=()|(ch=)p
23、ush(S,ch);else if (ch=)x=pop(S);if(x!=)printf(“括号不匹配括号不匹配”);return FLASE ;else if (ch=)x=pop(S);if(x!=()printf(“(括号不匹配括号不匹配”);return FLASE ;第27页,本讲稿共54页if (S.top!=0)printf(“括号数量不匹配!括号数量不匹配!”);return FLASE ;else return TRUE ;第28页,本讲稿共54页3.3栈与递归调用的实现栈与递归调用的实现(简简)栈的另一个重要应用是在程序设计语言中实现递归调用。栈的另一个重要应用是在程序设
24、计语言中实现递归调用。递归调用递归调用:一个函数一个函数(或过程或过程)直接或间接地调用自己本直接或间接地调用自己本身,简称身,简称递归递归(Recursive)。递归递归是程序设计中的一个强有力的工具。因为递归函数是程序设计中的一个强有力的工具。因为递归函数结构清晰,程序易读,正确性很容易得到证明。结构清晰,程序易读,正确性很容易得到证明。为了使递归调用不至于无终止地进行下去,实际上有为了使递归调用不至于无终止地进行下去,实际上有效的递归调用函数效的递归调用函数(或过程或过程)应包括两部分:应包括两部分:递推规则递推规则(方方法法),终止条件终止条件。例如:求例如:求n!第29页,本讲稿共5
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 队列 精品 文稿
限制150内