栈
栈是一种后进先出(Last in First Out)的数据结构,简称 LIFO。
啥叫后进先出呢?这就和打飞机,呃,打手枪一样,弹夹中最先插进去的子弹最后才打出去,越晚摁进去的子弹越早打出来。
别小看它,栈是一种很重要的编程概念,它在软件应用中很常见。我们每天都用到的浏览器就用到了,浏览器的“后退”按钮。
栈是线性表,那么它同样有顺序存储和链式存储
顺序栈
默认 top = -1 时为空栈,top=0 为第一个点
链式存储
链式存储的栈叫做链栈。
链栈用单链表实现,一般尾节点为栈底,使用头指针指向的节点作为栈顶,不需要头节点。top = NULL 为空栈。
同时因为顺序和链式本身的存储特点,顺序栈的元素个数是固定值,存在栈满的情况,而链式栈则不存在栈满的情况,除非内存被塞的满满的。
队列
队列是一种先进先出(First in First Out)的数据结构,简称 FIFO。
啥叫先进先出呢?这就和排队上厕所,谁先到谁先嘘嘘,到的晚的只能忍住。
同比栈,队列在软件应用中也很常见,就像现在我在一个字母一个字母的敲,最后输出在屏幕上你看到的一个个的字,这些就是最常见的队列的应用。
队列是限制仅在一端进行插入操作,在另一端进行删除操作的线性表。
允许删除的一端叫做队头,允许插入的一端叫做队尾。队列的插入叫做入队列,队列的删除叫做出队列。
【队列的存储结构】
同为线性表,队列也有链式存储和顺序存储。
链式存储
链式存储的队列叫做链队列。
其实这就是单链表,而且是带头节点的单链表,这样的话对于入队或者出队来说,它们的时间复杂度与单链表的插入和删除的时间复杂度都是一样的,都是 O(1)。
在此,头节点指向队头,用 head 指向头节点,tail 指向队尾。
当 head 和 tail 都指向头节点时,为空队列。
顺序存储
顺序存储的队列用数组实现。数组下标为 0 的一端为队头,用 head 指向,队尾用 tail 指向。
假设队列能存 5 个元素,当 head = tail,队列为空队列。
从上图的空栈中,A B C 依次入队,
执行三次入队操作,此时head = 0,tail = 3。可以看出,当入队列的时候,数据直接按序存储到数组中,时间复杂度为 O(1)。
如果此时要执行两次出队操作
执行两次出队操作,相当于删除了 A B,此时 head = 2,tail = 3。从这可以看出,出栈的时间复杂度也是 O(1)。
是不是现在想说一句:就这?
还真不是就这。此时我再入两次队列。
这个时候问题来了,我就大小为 5,数组最后一个元素已经被占了,此时再入栈的话,就数组越界了,但是我这个队列明明没满,我下标是 0 和 1 的位置还空着,这咋整?