数据结构-栈和队列

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

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

1、栈(stack)是限定仅在表尾进行插入和删除操作的线性表。又称后进先出(last in first out)LIFO结构。也即栈顶的元素先出栈。

2、栈的抽象数据类型(ADT:abstract data type)

data:同线性表, 元素具有相同的类型,相邻元素具有前驱和后继关系。栈本身就是一个线性表。

operation:初始化,出栈,入栈,删除,长度等等方法。

栈的元素从0开始入栈,所以一般空栈的栈顶变量top=-1

3、栈的顺序存储结构——栈的入栈和出栈,仅是插入或者取出栈顶元素。两者都没有涉及到任何循环语句,因此时间复杂度均是o(1)

4、栈的链式存储结构——和单链表类似。出栈和入栈的时间复杂度也是o(1),对于空间性能,顺序栈需要实现确定一个固定的长度,可能存在内存空间的浪费,但它的优势是存取时定位很方便,而链栈则要求每个元素都有指针域,这同时增加了一些内存开销,但对于栈的长度无限制。所以他们的区别和线性表讨论的一样,如果栈的使用过程中元素不可预料,那最好使用链栈,反之,如果变化在可控范围内,使用顺序栈会好一些。

5、栈的作用:栈的引入简化了程序设计的问题,划分了不同关注层次,使得范围缩小,更加聚焦于我们要解决的问题核心。反之,像数等,因为要分散经历去考虑数组的下标增减等细节问题,反而掩盖了问题的本质。

6、栈的应用—递归,一个直接调用自己或通过一系列调用语句间接地调用自己函数,称为递归函数。

  递归和迭代:迭代使用的是循环结构,递归使用的是选择结构。递归能使程序的结构更清晰,更简洁,更容易让理解,从而减少读懂代码的时间。但是大量的递归调用会建立函数的副本,会耗费大量的时间和内存。迭代不需要。因此应视不同情况选择不同的代码实现方式。

  递归和栈的关系:递归包含前行和退回阶段。退回的顺序使它前行顺序的逆序。前行阶段,每一层递归,函数的局部变量、参数值以及返回地址被压入栈中,退回阶段,位于栈顶的局部变量、参数值和返回地址被弹出,用于返回调用层次中执行代码的其余部分,也就是恢复了调用的状态。

  《数据结构—从应用到实现(Java版)》第8章递归。

7、栈的应用—四则元素表达式求值,后缀表达式:所有的符号都在数字的后面出现。例子:9+(3-1)*3+10/2 ->9 3 1 - 3 * + 10 2 / +

  中缀表达式转后缀表达式:从左到右遍历,数字输出,符号判断其与栈顶符号的优先级,如是右括号或优先级低于栈顶符号则栈顶元素一次出栈并输出,并将当前符号进栈。

  后缀表达式计算:从左到右遍历,遇到数字就进栈,遇到符号就将处于栈顶两个数字出栈,进行运算,运算结果进栈。

8、对于栈来说,如果是两个相同数据类型的栈,则可以用数组的两端作栈底的方法来让两个栈共享数据,这就可以最大化的利用数组的空间。

队列queue

1、对了是只允许在一段进行插入的操作,而在另一端进行删除操作的线性表。允许插入的一端称为队尾,允许删除的一端称为队头。是一种先进先出(FIFIO:First in First out)的线性表

 

 2、循环队列和链队列,类似之前的顺序链表和单链表。

3、对于队列来说,为了避免数组插入和删除时需要移动数据,于是引入了循环队列,使得队头和队尾可以在数组中循环变化。解决了移动数据的时间损耗,使得本来插入和删除是o(n)的时间复杂度变成了o(1).

posted @ 2019-07-01 15:40  仰望星空001  阅读(330)  评论(0编辑  收藏  举报