数据结构笔记——栈与队列

总述

栈和队列是我们在stl中比较熟悉的容器了,关于它的操作我们虽然有可能会混淆,但是应该很明白有什么操作、能怎么操作。

在数据结构里面,我们学习的重点不是如何使用栈与队列,而是学习这个容器的运行基本原理,为我们日后对容器应用的拓展打下基础。(当然能用stl里面的模板栈还是要用模板栈的,自己写万一写错又不知道该怎么改正了)

栈是一种先进后出的数据使用模式,常见题型为括号匹配、表达式计算、火车的进栈出栈问题

栈与线性表一样,都有顺序存储和链式存储两种,分别称为顺序栈和链栈。

顺序栈

顺序栈的模拟相对于链栈简单很多,也是我比较喜欢的模拟栈的方法。因为这个方法不容易出错,虽然有内存的限制,但是一般而言题目都会给定数的数目,不会造成内存溢出的情况~

但是在一般而言的情况下,链栈虽难,却是可以体现一个人的水平的重要标准。毕竟数组大家都会,然而指针就不一样啦。

顺序栈的定义需要注意的方面有:

  1. 在出栈时的判空以及在入栈时的判满,否则溢出
  2. 注意是先进行指针的+1.还是先写入数字。对于每个人的情况不同,顺序也不同,不能盲目背书,要学会活学活用。
  3. 构造函数的条件为,top=-1/0

顺序栈因为比较简单,基本没有难度,适合新手。

链栈

链栈跟单链表一样,是通过一个模拟点的struct跟一个类所构成的。

其实绝大部分内容跟单链表差不多,但是仍存在不同。

例如:

  1. 因为只需要在栈顶进行插入和删除的操作,所以不需要头节点就能是一样的操作(我们发现在单链表中有头节点的最大区别在于尾插的不同)。
  2. 并且进行头插相对于尾插更为简单,(尾插的删除操作需要O(N),但是头插只需要O(1)),一直有头指针指向第一个节点,进行它的插入以及删除即可。

队列

队列是一种先进先出的数据使用方式,常见题型为舞会

队列有顺序队列、循环队列和链队列三种,较为简单的为数组模拟的顺序队列,其次是链队列,我觉得最难的反而是循环队列,但是只要理解了我们也会发现,也没什么大不了的嘛。

顺序队列

顺序队列是用数组模拟的、用两个指针表示队头和队尾的队列,由于其数组最开始的部分一旦释放元素就不会再次使用,所以它的空间利用率较小,一般还是不使用为好。

顺序队列需要注意的问题有:

  1. 注意队尾指针指向那里
  2. 注意队头指针指向哪里
  3. 注意你这样设置时,队列为空、队列满的条件是什么

例如,如果设置队头指针front=0,队尾指针tail=0,从队尾进入元素,先填入数据,在进行tail+1。此时队列为空的条件为tail=top=0,满的条件为tail=maxsize。

循环队列

循环队列最大的好处在于空间的利用,学习了它之后相信我们对取余操作也更加的上手了。

循环队列的设置跟顺序队列相同,但是在放入元素和删除元素上有较大的区别。

区别在于:

  1. 队头队尾的设置仍为front=tail=0,但是队满时,因为需要浪费一个空间模拟队满,所以条件为(tail+1)%maxsize=front。这是栈慢与下溢的判定条件
  2. 入队操作此时以及固定,先tail=(tail+1)%maxsize,然后a[tail]=x
  3. 出队操作:front=(front+1)%maxsize
  4. 取队头:return a[(front+1)%maxsize];

链队列

链队列也是单链表的子集,操作基本相同

难点在于记住头部当队首简单还是尾部当队首简单

经过计算,头部当队首的话,需要进行的是尾插,插入耗时O(1),删除耗时O(1),因为头部为队尾,删除的是第一个元素。

头部当队首的话,进行头插,插入耗时O(1),删除耗时O(N),因为删除需要尾部删除,每次都需要遍历找到最尾部的前一个点。

学习情况

有现成的栈和队列就不想再模拟了,但是即使如此我们也要模拟啊!!我不能怠惰

倒是没有什么疑问,有的问题在刚刚整理博客的时候倒是思考的差不多了,很开心,写博客是很有好处的!

下节课就要学KMP算法了,有点紧张,当时学习KMP算法的时候,虽然看的明白了一点点,但是啊,果然还是太容易忘了!上次看书的时候一脸懵逼,只知道我学过……对算法的印象可能在于某个十分复杂的跳跃了,悲伤

你可能感兴趣的:(数据结构)