《数据结构》课件1第3章 栈和队列_第1页
《数据结构》课件1第3章 栈和队列_第2页
《数据结构》课件1第3章 栈和队列_第3页
《数据结构》课件1第3章 栈和队列_第4页
《数据结构》课件1第3章 栈和队列_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第3章栈和队列栈

栈的定义顺序栈的表示和实现

链栈的表示和实现队列队列的定义

循环队列

链队列3.1栈1.栈的定义2栈是限定仅在表的一端进行插入和删除操作的线性表,允许插入和删除的一端称为栈顶,另一端称为栈底。栈的插入操作称为入栈,栈的删除操作称为出栈。不含任何数据元素的栈称为空栈。设有栈S=(a1,a2,a3,,…,an),则一般称a1为栈底元素,an为栈顶元素。入栈:按a1,a2,a3,,…,an的顺序出栈:按an,an-1,…,a2,a1的顺序栈称为后进先出的线性表(LIFO:LastInFirstOut)a2a1an...栈底栈顶入栈出栈栈的基本操作操作结果intLength()返回栈元素个数boolEmpty()如栈为空,则返回true,否则返回falsevoidClear()清空栈boolPush(Te)插入元素e为新的栈顶元素boolTop(T&e)用e返回栈顶元素boolPop(T&e)删除栈顶元素,并用e返回栈顶元素3.1栈2.顺序栈的表示和实现3顺序栈是指利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。顺序栈可以用一维数组来实现。通常把数组中下标为0的一端作为栈底,同时附设变量top指示栈顶元素在数组中的位置。设存储栈的数组长度为maxSize,则栈空时栈顶位置top=-1,栈满时栈顶位置top=maxSize-1。入栈时,栈顶位置top加1;出栈时,栈顶位置top-1。3.1栈2.顺序栈的表示和实现4类模板定义template<typenameT>classSqStack{private: inttop; //栈顶元素在数组中的下标 intmaxSize; //栈可用的最大容量 T*elem; //存储空间的基地址public: SqStack(intsize=DEFAULT_SIZE); //构造函数SqStack(SqStack<T>&st); //复制构造函数 ~SqStack(); //析构函数 intLength(); //返回栈中元素个数boolEmpty(); //判断栈是否为空voidClear(); //清空栈 boolPush(Te); //入栈 boolPop(T&e); //出栈 boolGetTop(T&e); //返回栈顶元素};3.1栈2.顺序栈的表示和实现5基本操作//返回栈中元素个数template<typenameT>intSqStack<T>::Length(){ returntop+1;}//判断栈是否为空template<typenameT>boolSqStack<T>::Empty(){ returntop==-1;}//清空顺序表template<typenameT>voidSqStack<T>::Clear(){ top=-1;}//入栈template<typenameT>boolSqStack<T>::Push(Te){ if(top==maxSize-1) returnfalse; elem[++top]=e; returntrue;}//返回栈顶元素template<typenameT>boolSqStack<T>::GetTop(T&e){ if(top==-1) returnfalse; e=elem[top]; returntrue;}//出栈template<typenameT>boolSqStack<T>::Pop(T&e){ if(top==-1) returnfalse; e=elem[top--]; returntrue;}3.1栈3.链栈的表示和实现6链栈是指采用链式存储结构实现的栈,通常用单链表来表示。由于栈的插入和删除操作只能在栈顶执行,因此以单链表的头部作为栈顶是最方便的,而且没有必要像单链表那样为了运算方便附加一个头结点。链栈的结点结构与单链表的结点结构相同template<typenameT>structStNode{ Tdata; StNode<T>*next;};3.1栈3.链栈的表示和实现7类模板定义template<typenameT>classLinkStack{private: StNode<T>*top;

//栈顶指针public: LinkStack(); //构造函数 LinkStack(LinkStack<T>&lst); //复制构造函数 ~LinkStack(); //析构函数 intLength(); //返回栈中元素个数boolEmpty(); //判断栈是否为空 voidClear(); //清空栈boolPush(Te); //入栈 boolPop(T&e); //出栈 boolGetTop(T&e); //返回栈顶元素};3.1栈3.链栈的表示和实现8基本操作//返回栈中元素个数template<typenameT>intLinkStack<T>::Length(){ intlen=0; StNode<T>*p=top; while(p!=NULL) { len++; p=p->next; } returnlen;}//判断栈是否为空template<typenameT>boolLinkStack<T>::Empty(){ returntop==NULL;}//清空顺序表template<typenameT>voidLinkStack<T>::Clear(){ StNode<T>*p; while(top!=NULL) { p=top; top=p->next; deletep; }}//返回栈顶元素template<typenameT>boolLinkStack<T>::GetTop(T&e){ if(top==NULL) returnfalse; e=top->data; returntrue;}3.1栈3.链栈的表示和实现9入栈template<typenameT>boolLinkStack<T>::Push(Te){ StNode<T>*p=newStNode<T>; //生成新结点

if(p==NULL) //动态内存耗尽

returnfalse; p->data=e; //将新结点数据域置为e p->next=top; //将新结点插入栈顶

top=p; //修改栈顶指针

returntrue;}3.1栈3.链栈的表示和实现10出栈template<typenameT>boolLinkStack<T>::Pop(T&e){ if(top==NULL) //栈空

returnfalse; StNode<T>*old_top=top; e=old_top->data; //用e保存栈顶元素的值

top=old_top->next; //修改栈顶指针

deleteold_top; //释放原栈顶元素的空间

returntrue;}3.1栈4.栈的应用——进制转换问题11【问题分析】将十进制数转换为二进制数的方法很多,其中一个常用的算法是“除2取余法”。上述计算过程是从低位到高位顺序产生二进制数的各个数位,而输出过程应从高位到低位进行,恰好和计算过程相反,因此可以使用栈来解决这个问题。在计算过程中依次将得到的余数压入栈中,计算完毕后,将栈中的余数依次出栈输出,输出结果就是转换后的二进制数。【算法步骤】(1)当n≠0时重复执行以下操作:①计算n除以2的余数并将其压入栈中;②用n/2代替n。(2)重复执行以下操作直到栈为空:弹出栈顶元素,并输出被弹出元素的值。3.1栈4.栈的应用——括号匹配问题12【问题分析】给定一个算数表达式,目测怎么判断括号是否匹配呢?可以从左向右看这个表达式中的括号,看到一个“(”就记住它,如果下一个括号是“)”,则划掉这两个括号,如果下一个括号还是“(”,则暂时不管前一个“(”,先把它放在那里,等后面的“(”处理完再来处理它,这正好符合栈的后进先出特性,因此可以使用栈来解决这个问题。从左向右依次扫描表达式字符串中的各字符,若读入的是“(”,则进栈;若读入的是“)”,且栈不为空则出栈,如果栈空则说明没有与之匹配的左括号,匹配失败。当表达式扫描结束时,若栈为空则匹配成功,否则,说明没有与栈中的“(”相匹配的“)”,匹配失败。【算法步骤】(1)初始化一个空栈。(2)扫描表达式,依次读入字符,直到表达式扫描完毕。①如果读入的字符是’(‘,则将其压入栈;②如果读入的字符是’)‘,且栈非空,则弹出栈顶元素;如果栈为空,则括号不匹配,返回false。(3)如果栈为空,则左右括号匹配,返回true;否则括号不匹配,返回false。3.2队列1.队列的定义13队列的基本操作队列是限定只允许在一端进行插入操作,在另一端进行删除操作的线性表。允许删除(出队)的一端叫做队头允许插入(入队)的一端叫做队尾入队和出队的顺序相同先进先出(FIFO)a1a2a3

anfrontrear入队出队操作结果intLength()返回队列长度boolEmpty()如队列为空,则返回true,否则返回falsevoidClear()清空队列boolOutQueue(T&e)删除队头元素,并用e返回其值boolGetHead(T&e)用e返回队头元素boolInQueue(Te)插入元素e为新的队尾3.2队列2.循环队列——队列的顺序表示和实现14队列的顺序表示就是用一组地址连续的存储单元依次存放从队头到队尾的元素。可以用数组elem[maxSize]作为队列的顺序存储空间,maxSize为队列的容量,队头元素放在下标为0的一端由于队列的队头和队尾都是活动的,因此需要附设两个整型变量front和rear分别指示队头元素和队尾元素的位置。初始化创建空队列时,令front=rear=0,插入新元素时,rear加1;删除元素时,front加1。因此,在非空队列中,front始终指向队头元素,而rear始终指向队尾元素的下一个位置。假设当前队列分配的最大空间为6,则当队列处于图3-10(d)所示的状态时不可再继续插入新的队尾元素,否则会出现溢出现象,即因数组越界而导致的非法操作错误。事实上,此时队列的实际可用空间并未占满,所以这种现象称为“假溢出”。这是由“队尾入队,队头出队”这种受限制的操作造成的。3.2队列2.循环队列——队列的顺序表示和实现15解决假溢出的方法是将队列从逻辑上看成一个环——循环队列循环队列的首尾相接,当队头front和队尾rear进入到maxSize-1时,再进一个位置就自动地移动到0,可用取模运算来实现。队头进1:front=(front+1)%maxSize队尾进1:rear=(rear+1)%maxSize对于循环队列不能以front和rear的值是否相等来判断队列空间是空还是满。在这种情况下,如何区分队满还是队空呢?少用一个元素空间队列空间大小为n时,有n-1个元素就认为是队满。队空的条件:front==rear队满的条件:(rear+1)%maxSize==front另设一个标志位以区别队列是空还是满3.2队列2.循环队列——队列的顺序表示和实现16类模板定义template<typenameT>classSqQueue{pravite: intfront,rear; //指示队头和队尾的位置

intmaxSize; //队列的最大容量

T*elem; //存储空间的基地址

public: SqQueue(intsize=MAXSIZE); //构造函数

SqQueue(SqQueue<T>&sq); //复制构造函数

~SqQueue(); //析构函数

intLength(); //返回队列的长度

boolEmpty(); //判断队列是否为空

voidClear(); //清空队列

boolInQueue(Te); //入队

boolOutQueue(T&e); //出队

boolGetHead(T&e); //返回队头元素};3.2队列2.循环队列——队列的顺序表示和实现17基本操作//返回队列长度template<typenameT>intSqQueue<T>::Length(){ return(rear-front+maxSize)%maxSize;}//判断队列是否为空template<typenameT>boolSqQueue<T>::Empty(){ returnfront==rear;}//入队template<typenameT>boolSqQueue<T>::InQueue(Te){ if((rear+1)%maxSize==front) returnfalse; elem[rear]=e; rear=(rear+1)%maxSize; returntrue;}//清空队列template<typenameT>voidSqQueue<T>::Clear(){ rear=front=0;}//出队template<typenameT>boolSqQueue<T>::OutQueue(T&e){ if(rear==front) returnfalse; e=elem[front]; front=(front+1)%maxSize; returntrue;}//返回队头元素template<typenameT>boolSqQueue<T>::GetHead(T&e){ if(rear==front) returnfalse; e=elem[front]; returntrue;}3.2队列3.链队——队列的链式表示和实现18队列的链式存储结构称为链队,通常用单链表表示。结点结构与单链表的结点结构相同。队头队尾a1a2an

∧…头指针front尾指针rear头结点非空链队列:空链队列:∧头指针front尾指针rear头结点3.2队列3.链队——队列的链式表示和实现19类模板定义template<typenameT>classLinkQueue{private: QuNode<T>*front,*rear; public: LinkQueue(); //构造函数

LinkQueue(LinkQueue<T>&lq);

//复制构造函数

~LinkQueue(); //析构函数

intLength(); //返回队列长度

boolEmpty(); //判断队列是否为空

voidClear(); //清空队列

boolInQueue(Te); //入队

boolOutQueue(T&e); //出队

boolGetHead(T&e); //获取队头元素};3.2队列3.链队——队列的链式表示和实现20基本操作//返回队列长度template<typenameT>intLinkQueue<T>::Length(){ intlen=0; QuNode<T>*p=front->next; while(p!=NULL) { len++; p=p->next; } returnlen;}//判断队列是否为空template<typenameT>boolLinkQueue<T>::Empty(){ returnfront==rear;}//清空队列template<typenameT>voidLinkQueue<T>::Clear(){ QuNode<T>*p=front->next; while(p!=NULL) //删除所有数据结点

{ front->next=p->next; deletep; p=front->next; } rear=front; //rear指向头结点}//返回队头元素template<typenameT>boolLinkQueue<T>::GetHead(T&e){ if(front==rear) returnfalse; e=front->next->data; returntrue;}3.2队列3.链队——队列的链式表示和实现21入队template<typenameT>boolLinkQueue<T>::InQueue(Te){ QuNode<T>*p=newQuNode<T>; //生成新结点

if(p==NULL) //动态内存耗尽

returnfalse; p->data=e; p->next=NULL; rear->next=p; //新结点链入队尾

rear=p; //重新设置队尾指针

returntrue;}3.2队列3.链队——队列的链式表示和实现22出队template<typenameT>boolLi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论