先进者先出,这就是典型的“队列”。队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。队列跟栈一样,也是一种操作受限的线性表数据结构。
用数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列。 队列需要两个指针:一个是 head 指针,指向队头;一个是 tail 指针,指向队尾。
顺序栈:
在出队时可以不用搬移数据。如果没有空闲空间了,我们只需要在入队时,再集中触发一次数据的搬移操作。出队操作的时间复杂度仍然是 O(1),入队操作的时间复杂度也是 O(1) 。
链栈:
出队操作的时间复杂度仍然是 O(1),入队操作的时间复杂度也是 O(1) 。
1、循环队列
用数组来实现队列的时候,在 tail==n 时,会有数据搬移操作,这样入队操作性能就会受到影响,可以通过循环队列解决这一问题。
使用好循环队列的关键就是确定好队空和队满的判定条件,队列为空的判断条件仍然是 head == tail,当队满时,(tail+1)%n=head。
2、优先级队列
3、双向队列
- //顺序队列的实现
-
- package main
-
- import "fmt"
-
- type Queue struct {
- element []int
- }
-
- //创建一个新队列
- func NewQueue()*Queue{
- return &Queue{}
- }
-
- //判断队列是否为空
- func (s *Queue)IsEmpty()bool{
- if len(s.element) == 0 {
- return true
- }else {
- return false
- }
- }
-
- //求队列的长度
- func (s *Queue)GetQueueLength()int{
- return len(s.element)
- }
-
- //进队操作
- func (s *Queue)Push(value int) {
- s.element = append(s.element, value)
- }
-
- //出队操作
- func (s *Queue)Pop()bool{
- if s.IsEmpty(){
- return false
- }else{
- s.element = s.element[1:]
- }
- return true
- }
-
- //打印队列
- func (s *Queue)Print(){
- for i := 0;i <= s.GetQueueLength()-1;i++{
- fmt.Printf("%d ", s.element[i])
- }
- fmt.Printf("\n")
- }
-
- func main(){
- queue := NewQueue()
- queue.Push(1)
- queue.Push(3)
- queue.Push(5)
- queue.Print()
- queue.Pop()
- queue.Print()
- }
- //链队列
-
- //链式队列
-
- package main
-
- import "fmt"
-
- //节点
- type Node struct {
- next *Node
- data int
- }
-
- //链式队列
- type LinkQueue struct {
- head *Node
- tail *Node
- length int
- }
-
- //创建节点
- func CreateNode(value int) *Node{
- return &Node{
- nil,
- value,
- }
- }
-
- //创建链队列,初始化一个空头节点
- func CreateLinkQueue() *LinkQueue{
- return &LinkQueue{
- &Node{
- nil,
- 0,
- },
- &Node{
- next: nil,
- data: 0,
- },
- 0,
- }
- }
-
- //判断队列是否为空
- func (queue *LinkQueue)QueueEmpty()bool{
- return queue.head == queue.tail
- }
-
- //进队操作
- func (queue *LinkQueue)EnQueue(data int){
- p := CreateNode(data)
- queue.tail.next = p
- queue.tail = p
- queue.length++
- }
-
- //出队操作
- func (queue *LinkQueue)DeQueue()int{
- result := queue.head.next.data
- if queue.head.next != nil {
- queue.head = queue.head.next
- queue.length--
- }
- return result
- }
-
- //打印队列
- func (queue *LinkQueue)PrintQueue(){
- p := queue.head.next
- for p != nil {
- fmt.Println(p.data)
- p = p.next
- }
- }
-
- //获取队列长度
- func (queue *LinkQueue)GetLinkLength() int {
- return queue.length
- }
-
- func main(){
- queue := CreateLinkQueue()
- queue.tail = queue.head
-
- fmt.Println(queue.QueueEmpty())
-
- queue.EnQueue(1)
- queue.EnQueue(2)
- queue.EnQueue(3)
- queue.PrintQueue()
- fmt.Println(queue.GetLinkLength())
-
- fmt.Println()
- queue.DeQueue()
- queue.PrintQueue()
- fmt.Println(queue.GetLinkLength())
- }
1、实现一个循环队列
2、实现一个双端队列
3、实现一个优先级队列
4、滑动窗口最大值