大话数据结构(第四章 栈与队列)

栈是限定仅在表尾进行插入和删除操作的线性表。

队列是只允许在另一端进行插入操作、而在另一端进行删除操作的线性表。

  总结起来一句话形容:

    栈:先进后出,后进先出(Last In First Out)。

    允许插入和删除的端称之为栈顶(top),另一端称之为栈底(bottom),没元素的为空栈。简称LIFO结构。

    进栈、压栈、弹栈

1、栈的抽象数据类型

  栈,实际上线性表的操作特性它都具备,在插入和删除上有些变化,并改名为push和pop

2、栈的顺序存储结构及实现

  栈、顺序栈;用下标为0的一端作为栈底

  定义一个top变量指示栈顶元素的位置,空栈时,top定为-1

3、两栈共享空间

  一个栈如果空间用满了就有可能溢出,为了充分利用空间。

  我们把两个栈的未利用空间共享。

  具体操作方法如下:

    一个栈有两端,一个数组有两端,让一个栈的栈底为数组的起始,另一个栈的末端为数组长度n-1处,这样当两个栈压栈时候,是从两端向中间延伸。

  栈满的情况,当两个栈顶相差1时,栈满。

  使用这种栈结构方式一般是两个栈空间有相反的需求关系的时候。

4、栈的链式存储结构及实现

  链的顺序存储结构,简称链栈。

  与单链表类似,只是插入删除有所区别,他们的进出事件复杂度均为O(1)

  顺序栈与链栈 事件复杂度一样,顺序栈需要一个固定的长度,可能存在空间浪费问题,优势是存取方便,链栈每一个元素都有指针域,增加内存开销。

4、栈的作用

  有的人想,既然都用数组或者链表能完成,为什么不直接用他们,非要封装这样的数据结构呢?

  其实为什么要做飞机、汽车、轮船呢,世界上很多位置都能用脚抵达,但是我们关注的是到达而不是去的过程,这个而过程可以用各种方式封装起来,栈也是这样的作用。栈的引入简化了程序设计问题,划分了不同的关注层次,使得思考范围缩小,聚焦我们的核心问题,而像数组,如果分散精力去考虑数组下标的增减等细节问题,会浪费精力,掩盖问题本质。现在很多高级语言,都有对栈的结构封装,不用关注细节,直接使用Stack的push和pop方法,非常方便。

5、栈的应用-递归

  栈有一个很重要的应用,在程序设计语言中实现了递归。 

  例子:斐波那契数列实现(Fibonacci) 

  一对兔子出生两个月后就有繁殖能力,一对兔子每个月能生出一队小兔子,假设兔子不死,一年后可以繁殖多少对兔子?

  一种方式是使用for循环迭代,另一方面是递归调用自己。每一层递归,函数的局部变量、参数值、返回的地址都压入栈中,退回阶段,位于顶端的局部变狼、参数值好返回地址呗弹出,用于执行调用层次中其余代码部分。

  递归的前行和回退

6、栈的应用-四则运算表达式求值

  四则运算

  后缀表达式,从左到右遍历后缀表达式,遇到数字进栈,遇到符号则取出两个数字运算,结果再进栈。

  平时使用的四则运算表达式称作中缀表达式

7、队列的定义

  允许一段进行插入操作,而另一端进行删除操作的线性表(First In First Out)

  队列的抽象数据类型:插入只能在队尾,删除只能在队头进行。

  同样的,队列是线性表,也有顺序存储和链式存储。

  队列的顺序存储中,取元素从队头出,会移动元素

  循环队列定义:队列头尾相接的顺序存储结构称为循环队列

8、队列的链式存储结构及实现

  尾进头出

 

 

  

  

posted @ 2018-01-18 15:08  拔出萝卜带出土豆  阅读(135)  评论(0编辑  收藏  举报