数据结构-栈和队列

    在逻辑结构上栈和队列还是线性表。但是这俩和线性表的区别在于它们基本运算是线性表基本运算的子集,即有些线性表的基本操作栈和队列是没有的。也就是我们说的栈和队列是运算受限的线性表。在计算机中函数的调用、程序的递归处理,括号匹配等用到的是栈。而打印服务等则用队列来实现。

定义

     栈(stack):是插入和删除运算限定在某一端的线性表,允许插入删除操作的端为栈顶(top),另一端为栈底(bottom)。
     队列(queue):是允许在一端插入另一端删除的线性表,插入一端为队尾(rear),删除一端为队头(front)。

存储结构

    顺序存储

     栈:用一组连续的存储单元存放栈中的元素,也称为顺序栈。栈由TOP指针的+-1来对应出入栈操作。初始化空栈是top=0。当top=0时做出栈操作会引起“下溢”。通常我们用一维数组和一个变量来实现栈,因为栈的顺序存储空间是事先分配的,即固定。所以当top=数组长度时,即栈满状态,做入栈操作导致“上溢”。如图所示,需要知道的是0存储单元是不存在的或者是0号存储单元不存储数据。,即top=0是空栈的标志。
             
    队列:用一组连续的存储单元存放队列元素,也称为顺序队列。由一个front指针+1来出队,由一个rear指针+1来入队。这里都是+1是因为队列有两个指针且两端操作不同,所以只能通过+1来实现,思考一下。也就是这个导致了顺序队列存在一个问题,即当front=队列长度时队列无法再执行入队操作。因为,rear指针无法回复到rear=0的状态(都只加不减所以无法回去)。如图:

             为解决这个问题就出现了循环队列的概念,这里的循环队列不是在结构上有什么改变。而只是在入队操作时不再是单纯的+1而是通过除法取余来确定入队的数据的存储单元。以上图为列全部出队后rear=4即队满状态,那么这时再入队我们不是直接+1而是(4+1)mod 4得到余1,即我们将要把新的元素存储1号存储单元。这就解决了rear指针不能回头的问题。这个图不太好处理,就不上图了啊。这里还需要注意的是,原来对列判空的条件为rear=front=0,循环队列就变成了rear=front。

    链式存储

    链式存储这一块没有特别需要讲的东西。除了一个表头节点需要注意一下。表头节点的引入在我自己认为,主要是为了保持链式存储结构的一个稳定性。首先,我们知道头指针指向的是链表的头节点(首元素),也就相当于头指针是单链表的入口吧。这里就有一种情况,我们可能会对头节点进行删除或者在其前插入新元素。这时就发现我们需要修改头指针来改变这个单链表的入口,偷换下概念就是“接口不稳定”。

    因此就引入了一个空的节点放在首元素之前,这样就保证了单链表的入口是稳定的。同时对首元素之前的插入操作或者是对它删除操作就和之后的节点同样了。这就是表头节点的作用。不过这些都是自己思考的结果,没有什么很科学的依据。有什么问题的话,各位还望各位看客指点一下。

 应用

    这里就提一下使用栈来匹配括号的应用。大家知道每个文章中的括号都是成对出现的,同时也知道如果有括号嵌套在一起使用的话肯定是最后出现的左括号最先有右括号,如 {[()]} 。这就符合了栈的定义,就这么简单的提一下。那么本篇博客就到这里,下回再见吧!
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值