数据结构与算法学习笔记:栈与队列


基本定义:

                首先,栈与队列都属于线性表的范畴。所以,它们都具有线性表的基本属性:线性表中的每一个元素都是一对一的关系,除了表头结点与表尾结点 (如果有的话,线性表可以为空,即含有零个元素) 之外,表中每一个结点的都有且仅有一个前驱结点和一个后继结点。

        而栈和队列这两种数据结构,是在线性表的基础上,对其操作方法进行了限制,从而产生了不同的用法和用途。下面将阐述这两者的特点与基本用法。



基本概念:

           (Stack) 是一种特殊的线性表。它的特殊性在于,我们在对它进行操作的时候,只能在其一端进行操作,就像一个装羽毛球的筒,我们只能在筒口处取出或者放进羽毛球,但是最先放进去的羽毛球位于筒的底部,所以在取羽毛球的时候,最先放进去的羽毛球反而是最后取出来的那个。栈进行元素操作的那一端称为栈顶 (Top) ,而另一端也就当然地叫它栈底。根据栈的特点,它又被称为 LIFO 线性表 (Last In First Out),即后进先出的线性表。

       当然,这些操作方式是人为规定的,并不是完全没有办法在栈的其他位置进行操作,但是在实际操作中谁会这样去干呢。 


基本操作:

          对栈的基本操作有:

  1. 初始化栈,产生一个空栈:InitStack (Stack) ;
  2. 元素进栈 (或称压栈、入栈) , 将一个元素压入栈中: StackPush (Stack,Elm) ;
  3. 元素出栈 (或称退栈) ,将一个元素从栈中取出: StackPop (Stack) ;
  4. 获取栈顶元素 ,获取栈顶元素中的数据,只获取数据,并不取出该元素:StackTop (Stack) ;
  5. 判断栈空: StackEmpty (Stack) ;
  6. 判断栈满 :StackFull (Stack) ;

存储方式:

          栈的存储方式有两种,一种是顺序存储,另一种是链式存储,而不同的存储方式有不同的优点和缺点。

  1. 顺序存储:顺序存储方式主要是通过数组的形式存储的,顺序存储的方式优点在于对栈的创建,压栈,退栈等操作十分简便,而且在结构上更容易理解。但其缺点在于,顺序存储的容量是不可变的,不能动态地对其容量上限进行扩充,所以在使用过程中需要注意栈的 "上溢","下溢" 问题。
  2. 链式存储:链式存储方式主要是通过链表的形式存储的,链式存储的优点在于栈的容量是可以动态增加或减少的,这样就不存在 "上溢", "下溢" 的问题。但是链式存储也有它的不足之处,链式栈在操作方面比顺序栈更为繁琐,并且链式栈需要保存指针,增大了空间开销。

栈的应用:

            栈因其特殊的操作方式在很多场合都发挥着重要的作用,它最大的作用就是用于 "回溯",例如,著名的汉诺塔问题,如果要用编程方式解决的话就需要用到栈结构,还有走迷宫的问题,每当走错路的时候,都需要回溯到上一步来重新走,直到走对,这就需要用到栈结构。同时,编写程序中的递归算法也是靠栈结构实现的,所以,栈是一种十分重要的数据结构,虽然它很简单,但也需要好好练习熟悉。

队列


基本概念

              队列 (Queue) 是一种特殊的线性表。顾名思义,它的特殊之处就在于其操作方式就像排队一样,只能从其一端添加元素,另一端删除元素。所以队列的添加元素的一端 (只进不出) 称为队尾,删除元素的那一端 () 成为队头,根据队列的特点,又将其称为 FIFO 线性表 (First In First Out) ,也即先进先出线性表。


基本操作

        队列的基本操作有:

  1. 初始化栈 : InitQueue (Queue) ;
  2. 入队,将元素从队尾添加到队列中 : EnterQueue (Queue, Elem) ;
  3. 出队,将元素从队头删除 : DelQueue (Queue) ;
  4. 判断队满 : QueueEmpty (Queue) ;
  5. 判断队空 : QueueFull (Queue) ;
  6. 获取队头数据,只获取队头元素地数据,并不将其删除 : QueueFront (Queue) ;

存储方式

        队列的存储方式也有两种,一种是顺序存储,另一种是链式存储。

  1. 顺序存储:顺序存储主要是通过数组形式存储队列,对于这种存储方式,它与栈的顺序存储方式优缺点很相似,但在此之上,我们需要注意的是队列的 "假溢出" 问题。  那么何为 "假溢出" 问题呢? 一般的,我们在使用顺序存储形式的队列时,是使用数组下标来分别表示 队头指针 和 队尾指针 ,初始时,队头指针和队尾指针都指向数组第一个元素,每次入队一个元素,则将队尾指针后移一位,每次出队一个元素,就将队头指针后移一位,但是顺序存储的队列的长度是固定的,如果队尾指针指向了数组的最后一个元素,但队头指针并不在初始位置,而是已经后移了几位,此时如果再进行入队操作就会出现队尾指针越界的问题,但整个队列并没有超过长度限制,这就是队列的 "假溢出" 问题。 那么,如何去解决队列的 "假溢出" 问题呢? 这就需要将队列的操作稍作修改,每当队尾指针或队头指针指向数组的最后一个元素,并且需要后移一位时,就进行一次判断,若队列未满则将其修改为指向数组第一个元素。这样就相当于将数组的首尾连接起来,成为一个环。这种队列就称为 "循环队列" 。
  2. 链式存储:链式存储主要是通过链表形式存储队列,队列的链式存储与栈的链式存储优缺点也很相似,因为链表的长度不固定,所以就不存在 "假溢出" 的问题。但链式存储的空间开销要大于顺序存储,同时,其基本操作也比较复杂。

队列的应用:

             队列在计算机的很多地方都有应用,最明显的莫过于计算机的输入缓冲区,当计算机处理大量任务时,操作员会发现他输入的一串字符并没有立刻在计算机的显示屏上出现,在等待一段时间后,计算机会按照刚才输入的顺序将字符输出在显示屏上,这就是依靠队列结构完成的,计算机每次接收的字符都会被以队列的形式存放在输入缓冲区中,当计算机需要将其输出时,则将缓冲区中的字符依次出队,并打印在显示屏上。计算机中运用到队列的地方数不胜数,所以,队列虽然是最简单的数据结构之一,我们也需要花时间将其梳理清楚。














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值