ImageVerifierCode 换一换
格式:DOCX , 页数:25 ,大小:125.53KB ,
资源ID:20367906      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/20367906.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(第栈和队列3Word文档格式.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

第栈和队列3Word文档格式.docx

1、如果 S已满则返回1,否则返回0。因为链栈的结点空间系动态分配,所以结束栈的操作后需要释放掉所有动态分配空间,所以链栈的基本运算中相应地也增加了一个运算: Destroy(S):销毁链栈 释放链栈S的所有结点空间。3.1.2 栈的顺序存储结构及其基本运算的实现栈的顺序存储结构是利用一维数组来依次存放从栈底到栈顶的元素,由于栈限定为只能够在栈顶插入,因此可以只使用一个标志top来表示当前的栈顶位置。为算法设计的方便,通常以数组下标小的一端作为栈底,下标大的一端作为栈顶,插入和删除元素时,直接修改top的值就可以完成了:空栈时top的值为-1;进栈时top首先加1,元素再进栈;出栈时首先返回元素值

2、,然后top再减去1;当top等于数组的最大下标时,栈就满了。图3.2 顺序栈的进栈、出栈过程示意顺序栈的进栈与出栈的过程如图3.2所示。以下是用C/C+语言描述的顺序栈的数据类型:#define MaxSize 100 /*最大元素个数*/typedef struct /*顺序栈的类型定义*/ ElemType dataMaxSize; /*栈元素存储空间*/ int top; /*栈顶指针*/ SeqStack;以下是顺序栈基本操作的算法实现。(1)顺序栈的初始化void StackInitial(SeqStack *pS) /*创建一个由指针pS所指向的空顺序栈*/ pS - top =

3、 -1;(2)顺序栈判空int IsEmpty(SeqStack *pS) /*顺序栈为空时返回1,否则返回0*/ return pS - top = -1;(3)顺序栈判满int IsFull(SeqStack *pS) /*栈为满时返回1,否则返回0*/ top = MaxSize - 1;(4)元素进栈void Push(SeqStack *pS, ElemType e) /*若栈不满,则元素e进栈*/ if (IsFull(pS) /*栈已满,退出*/ printf(栈满溢出!n); exit(1); data + pS - top = e;(5)元素出栈ElemType Pop(Se

4、qStack *pS) /*若栈不为空,则删除栈顶元素,并返回它的值*/ if (IsEmpty(pS) /*栈为空,退出*/空栈! data pS - top - ;(6)取栈顶元素值ElemType GetTop(SeqStack *pS) /*若栈不为空,则返回栈顶元素的值*/ top ;(7)栈置空void MakeEmpty(SeqStack *pS) /*将由指针pS所指向的栈变为空栈*/3.1.3 栈的链式存储结构及其基本运算的实现栈的链式存储结构通常采用单链表表示,结点结构与单链表的一致,同样需要数据域和指针域。由于栈只需要固定在表的某一个端点进行插入和删除操作,所以将链表的表

5、头作为栈顶实现起来最为方便,而且没有表头结点操作起来更为简单。但是为了与前面的带表头结点的链表统一处理,所以给其加上表头结点,所有初始化和判断条件需要作相应的更改。图3.3 链栈的进栈、出栈过程示意链栈及其进栈与出栈的过程如图3.3所示。以下是用C/C+语言描述的链栈的数据类型:typedef struct stackNode /*链栈结点的类型定义*/ ElemType data; /*数据域*/ struct stackNode *next; /*指针域*/ StackNode;typedef struct /*链栈的类型定义*/ StackNode *top; /*栈顶指针*/ Link

6、Stack;以下是链栈基本操作算法的实现。(1)链栈的初始化void StackInitial(LinkStack *pS) /*指针pS所指向的链栈初始化为有表头结点链表*/ StackNode *p; p = (StackNode *) malloc(sizeof(StackNode); if (p = NULL) /*内存分配失败,退出*/内存分配失败! p - next = NULL; /*头结点指针域置空*/ top = p;(2)链栈判空int IsEmpty(LinkStack *pS) /*链栈为空时返回1,否则返回0*/ top - next = NULL;(3)元素进栈vo

7、id Push(LinkStack *pS, ElemType e) /*将元素e插入到栈顶*/ if (p = NULL) /*内存分配失败*/ data = e; next = pS - next; /*栈顶插入*/ next = p;(4)元素出栈ElemType Pop(LinkStack *pS) ElemType temp; if (IsEmpty(pS) /*栈为空,退出*/ p = pS - temp = p - data; /*保存栈顶结点数据*/ next = p - /*栈顶指针后移*/ free(p); /*释放结点*/ return temp;(5)取栈顶元素值Ele

8、mType GetTop(LinkStack *pS) if (IsEmpty(pS) /*栈为空,退出*/ return p -(6)栈置空void MakeEmpty(LinkStack *pS) /*将链栈设置为空栈,仅保留头结点*/ StackNode *p, *q; /*p为当前结点指针*/ /*从第一个结点开始*/ while (p != NULL) /*当没有到达栈底时*/ q = p; /*暂存当前结点指针*/ p = p - /*当前结点指针后移*/ free(q); /*头结点指针域置空*/(7)栈销毁void Destroy(LinkStack *pS) /*释放链栈所有

9、结点的存储空间*/ top; /*从第一个结点开始*/= NULL) top = NULL; /*栈顶指针置空*/3.1.4 栈的应用举例栈的应用较多,以下是一些典型应用实例。1进制转换编写算法将非负的十进制整数转换为其他进制的数输出,10及其以上的数字用从A开始的字母表示。十进制整数转换其他进制整数方法通常采用的是“除以基数取余数”,依次对除以基数得到的商再次求余数得到的值,为待转换进制数的从低位到高位,当商为0时,转换完毕。具体实现时采用栈暂时存放每次除得到的余数,当算法结束时(也就是商为0时),从栈顶到栈底就是转换后从高位到低位的数字。对应的算法如下:typedef char ElemT

10、ype;static char pszResult100; /*用于存放转换后的进制的字符串*/void Transform(unsigned long int nDecimal, unsigned short int nBase) /*将nDecimal的十进制数转换为nBase(2 nBase 36, 且 10)进制数*/ SeqStack stack; char ch; int i = 0; if (nBase 36 | nBase = 10) /*待转换的进制不合适*/待转换的进制错误! StackInitial(&stack); while (nDecimal != 0) ch =

11、(char) (nDecimal % nBase); /*求余数并转换为字符*/ ch = ch + (ch 10 ? 48 : 65 10); /*对转换得的字符做修正, 在0.9中间直接用0.9表示,48为 的ASCII码; 大于9则采用Z表示,65为 的ASCII码*/ Push(&stack, ch); /*进栈*/ nDecimal /= nBase; /*继续求更高位*/ while (! IsEmpty(&stack) pszResult i + = Pop(& /*出栈时存放在数组中*/ pszResulti = 0; /*加入字符串结束标志*/2回文判断回文指的是一个字符串从

12、前面读和从后面读都一样,如:abcba、123454321,编写算法判断一个字符串是否为回文。由于回文是从前到后以及从后到前都是一样的,所以只要将待判断的字符串颠倒,然后与原字符串相比较,就可以决定是否回文了。将字符串从头到尾的各个字符依次放入一个栈中,由于栈的特点是后进先出,则从栈顶到栈底的各个字符,正好是字符串从尾到头的各个字符;然后将字符串从头到尾的各个字符,依次与从栈顶到栈底的各个字符相比较,如果两者不相同,则表明该字符串不是回文,相同则继续比较;如果相互之间相匹配直到比较完毕,则说明该字符串是回文。int IsPalindrome(char pszText ) /*判断给定字符串ps

13、zText是否回文,是返回1,否则返回0*/ /*字符串的下标*/ char ch, temp; while (ch = pszText i + ) != ) /*所有字符依次全部进栈*/ i = 0; /*字符串下标复位*/stack) /*栈不为空*/ temp = Pop(& /*栈顶字符*/ if (temp != pszText i + ) /*两者字符不相同*/ return 0; return 1;3括号匹配设一个算术表达式中间可以包括三种括号:圆括号“(”和“)”、方括号“”和“”、以及花括号“”和“”,并且这三种括号可以按照任意的次序嵌套使用,但是不能相互交叉使用,如“()”

14、就是错误的,“ ()()”为正确的,设计算法判断给定表达式中所含括号是否正确配对。在表达式中从左向右检查,三种括号可以按序依次对消的就是正确格式的表达式,否则不正确,例如:( ()或 ( ) 格式正确 () 或 ( () 或 ()格式不正确表达式中间可能出现的不匹配的情况如下:(1)到来的右括号与栈顶的左括号并不匹配(2)栈为空时,到来右括号(3)直到结束,也没等到所“期待”的括号算法过程如下:从左向右按字符扫描表达式直到结尾(1)如果该字符是“左括号”则进栈;(2)如果该字符是“右括号”,首先检查栈是否空:如果栈为空,则表明该“右括号”多余,返回;否则该字符与出栈的栈顶元素相比较:如果两者相

15、匹配对消,则继续执行否则表明不匹配,返回;(3) 其他字符继续执行;(4)当表达式检验结束时,如果栈空,则表明表达式中匹配正确,返回正确值;否则,表明“左括号”有余,返回。enum /*枚举表达式中括号出现的所有情况*/ MATCH = 1, /*括号完全匹配*/ NOT_MATCH = 2, /*括号不匹配*/ LEFT_MORE = 3, /*左边括号多*/ RIGHT_MORE = 4, /*右边括号先出现*/;int IsPair(char cLeft, char cRight) /*判断右边括号与左边括号是否配对,是返回1,否则返回0*/ return cLeft = ( & cRi

16、ght = ) | cLeft = | cLeft = int IsMatch(char pszExpression ) /*判断字符串pszExpression中存放的表达式的括号是否匹配*/ /*栈初始化*/ while (ch = pszExpression i + ) !) /*当字符串pszExpression没有扫描完*/ switch (ch) case : /*如果是左边括号则直接进栈*/ Push(& break; /*右边括号*/ if (IsEmpty(&stack) /*栈空表示右边括号先来到*/ return RIGHT_MORE; temp = Pop(&stack

17、), if (! IsPair(temp, ch) /*右括号与栈顶括号不匹配*/ return NOT_MATCH; /*两者匹配则继续向后扫描*/ default: /*其它字符的处理部分*/ /*字符串到这里已经处理完毕*/ if (!stack) /*栈不空表示栈中还有左边括号未匹配*/ return LEFT_MORE; return MATCH; /*匹配成功*/3.2 队列(Queue)3.2.1 队列的定义队列是限制为仅仅能在表的一端插入和另一端删除的线性表,是生活中排队的抽象。插入的一端称为队尾(Rear)、插入操作通称进队(Enqueue);删除的一端称为队头(Front)

18、、删除操作通称出队(Dequeue);图3.4 队列的示意图类似于栈,没有元素的队列通称为空队列。依据队列的定义,队头的元素,最先进队列,也是最先出队列;队尾的元素正好相反总是最后进队列的,并且前面的所有元素没有出队前,该元素是不可能出队的,因此,队列有着先进先出(First In First Out FIFO)的特性,也称为先进先出表。操作系统中大量使用队列来管理各类进程和缓冲输入输出的信息,在日常生活中的排队就是“先进先出”的完整写照。队列由于同样属于特殊的线性表,类似于栈的实现,线性表的顺序存储结构和链式存储结构均可以用于队列的实现,通称顺序存储结构上实现的栈为顺序队列,链式存储结构上实

19、现的队列为链式队列。队列的基本运算主要如下: QueueInitial(Q):初始化 初始化队列Q为空。 IsEmpty(Q):队列判空 如果 Q为空则返回1,否则返回0。 EnQueue(Q, e):进队列 在队列Q的尾部插入数据元素e。 DeQueue(Q):出队列 如果队列Q不为空,将队头元素删除,并且函数返回该元素的值。 GetFront(Q):取队头元素 如果队列Q不为空,函数返回队头元素的值。 MakeEmpty(Q):队列置空 将队列Q设置为空栈。在每次出队列时同样需要判断队列是否为空,为空时,通称为下溢(Underflow);由于顺序队列的空间大小在声明时已经严格限制,所以在进

20、队列时需要判断队列是否已满,已满的队列再进队则通称为上溢(Overflow),顺序队列的基本运算中相应地增加了一个运算: IsFull(Q):队列判满 如果 Q已满则返回1,否则返回0。因为链式队列的结点空间系动态分配,所以结束队列的操作后也需要释放掉所有动态分配空间,所以链式队列的基本运算中相应地也增加了一个运算: Destroy(Q):销毁链式队列 释放链式队列Q的所有结点空间。3.2.2 队列的顺序存储结构及其基本运算的实现队列的顺序存储结构同样也是利用一维数组来依次存放从队尾到队头的元素,由于队列限定为只能够在队尾插入、队头删除,在插入删除元素如果不移动队列中的数据元素,就需要使用两个

21、活动标志:front来指示队列当前队头元素的位置、rear来指示队列当前队尾元素的位置。为算法设计的方便,通常以数组下标小的一端作为队头,下标大的一端作为队尾,插入和删除元素时,直接修改front和rear的值就可以完成了,删除元素时从现象上看是队头追赶队尾。为了队列操作的方便,通常约定队头标志front指向队头元素的前一个位置,队尾标志rear指向队尾元素,此时计算队列的长度、初始化操作等等可以做到统一。图3.5 顺序队列的进队、出队过程示意初始时空队列的front和rear的值均为0;入队时rear首先加1,元素再进队;出队列时首先front加1,然后再返回元素值。顺序队列的进队与出队的过

22、程如图3.5所示:这样的顺序队列随着插入和删除操作的进行,队头和队尾标志顺序向后移动,当元素被插入到数组中的最高位置上之后,队列的空间就用完了,如图3.5(4)。如果此时再插入元素,虽然数组的低端还有许多空闲空间,但已经无法插入,这种现象通称为顺序队列的“假溢出”。为解决顺序队列的“假溢出”,可以将存储队列的数组看作是首尾相连的循环结构,亦即将数组中最大下标的位置与最小下标相接,通过取余数操作即可很容易地实现,这种头尾相接顺序存储的队列通称为“循环队列”,如图3.6(1)所示:循环队列虽然解决了“假溢出”,随之又带来了新的问题:队列为空和为满的判定问题:图3.6 循环队列的示意图如图3.6(2)所示,当队列中元素不停地出队,队头标志front追上队尾标志rear,此时队列为空,有front = rear;另一种情况下,当队列中元素不停地入队,队尾标志rear追上队头标志front时,此时队列已满,此时同样有front = rear,如图3.6(3)所示,如何区分这两种情况?解决循环队列的队满和队空状态判定问题的解决方法通常有三种:方法1 :少用一个存储空间front永远指向队头元素的前一个位置,队列中有一个元素空间不可用队空判断条件:rear = front队满判断条件:(rear + 1) % MaxSize = front方法2 :设置标

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1