• 数据结构与算法 -- 队列


    一、队列定义

            先进者先出,这就是典型的“队列”。队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。队列跟栈一样,也是一种操作受限的线性表数据结构。

                           

     

            用数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列。 队列需要两个指针:一个是 head 指针,指向队头;一个是 tail 指针,指向队尾。

    二、复杂度分析

            顺序栈:

            在出队时可以不用搬移数据。如果没有空闲空间了,我们只需要在入队时,再集中触发一次数据的搬移操作。出队操作的时间复杂度仍然是 O(1),入队操作的时间复杂度也是 O(1) 。

                                     

     

            链栈:

             出队操作的时间复杂度仍然是 O(1),入队操作的时间复杂度也是 O(1) 。

                         

    三、特殊队列

    1、循环队列

            用数组来实现队列的时候,在 tail==n 时,会有数据搬移操作,这样入队操作性能就会受到影响,可以通过循环队列解决这一问题。 

                                         

            使用好循环队列的关键就是确定好队空和队满的判定条件,队列为空的判断条件仍然是 head == tail,当队满时,(tail+1)%n=head。

     2、优先级队列

     3、双向队列 

    四、队列的实现

    1. //顺序队列的实现
    2. package main
    3. import "fmt"
    4. type Queue struct {
    5. element []int
    6. }
    7. //创建一个新队列
    8. func NewQueue()*Queue{
    9. return &Queue{}
    10. }
    11. //判断队列是否为空
    12. func (s *Queue)IsEmpty()bool{
    13. if len(s.element) == 0 {
    14. return true
    15. }else {
    16. return false
    17. }
    18. }
    19. //求队列的长度
    20. func (s *Queue)GetQueueLength()int{
    21. return len(s.element)
    22. }
    23. //进队操作
    24. func (s *Queue)Push(value int) {
    25. s.element = append(s.element, value)
    26. }
    27. //出队操作
    28. func (s *Queue)Pop()bool{
    29. if s.IsEmpty(){
    30. return false
    31. }else{
    32. s.element = s.element[1:]
    33. }
    34. return true
    35. }
    36. //打印队列
    37. func (s *Queue)Print(){
    38. for i := 0;i <= s.GetQueueLength()-1;i++{
    39. fmt.Printf("%d ", s.element[i])
    40. }
    41. fmt.Printf("\n")
    42. }
    43. func main(){
    44. queue := NewQueue()
    45. queue.Push(1)
    46. queue.Push(3)
    47. queue.Push(5)
    48. queue.Print()
    49. queue.Pop()
    50. queue.Print()
    51. }

    1. //链队列
    2. //链式队列
    3. package main
    4. import "fmt"
    5. //节点
    6. type Node struct {
    7. next *Node
    8. data int
    9. }
    10. //链式队列
    11. type LinkQueue struct {
    12. head *Node
    13. tail *Node
    14. length int
    15. }
    16. //创建节点
    17. func CreateNode(value int) *Node{
    18. return &Node{
    19. nil,
    20. value,
    21. }
    22. }
    23. //创建链队列,初始化一个空头节点
    24. func CreateLinkQueue() *LinkQueue{
    25. return &LinkQueue{
    26. &Node{
    27. nil,
    28. 0,
    29. },
    30. &Node{
    31. next: nil,
    32. data: 0,
    33. },
    34. 0,
    35. }
    36. }
    37. //判断队列是否为空
    38. func (queue *LinkQueue)QueueEmpty()bool{
    39. return queue.head == queue.tail
    40. }
    41. //进队操作
    42. func (queue *LinkQueue)EnQueue(data int){
    43. p := CreateNode(data)
    44. queue.tail.next = p
    45. queue.tail = p
    46. queue.length++
    47. }
    48. //出队操作
    49. func (queue *LinkQueue)DeQueue()int{
    50. result := queue.head.next.data
    51. if queue.head.next != nil {
    52. queue.head = queue.head.next
    53. queue.length--
    54. }
    55. return result
    56. }
    57. //打印队列
    58. func (queue *LinkQueue)PrintQueue(){
    59. p := queue.head.next
    60. for p != nil {
    61. fmt.Println(p.data)
    62. p = p.next
    63. }
    64. }
    65. //获取队列长度
    66. func (queue *LinkQueue)GetLinkLength() int {
    67. return queue.length
    68. }
    69. func main(){
    70. queue := CreateLinkQueue()
    71. queue.tail = queue.head
    72. fmt.Println(queue.QueueEmpty())
    73. queue.EnQueue(1)
    74. queue.EnQueue(2)
    75. queue.EnQueue(3)
    76. queue.PrintQueue()
    77. fmt.Println(queue.GetLinkLength())
    78. fmt.Println()
    79. queue.DeQueue()
    80. queue.PrintQueue()
    81. fmt.Println(queue.GetLinkLength())
    82. }

    五、队列的应用

    1、实现一个循环队列

    2、实现一个双端队列

    3、实现一个优先级队列

    4、滑动窗口最大值

    声明:本文参考极客时间《数据结构与算法之美》

  • 相关阅读:
    拆解常见的6类爆款标题写作技巧!
    Python+AI给老照片上色
    【深入理解Kotlin协程】CoroutineScope.launch源码追踪扒皮
    MySQL 创建和管理表
    番外---10.1 gcc+make调试程序
    LitePal for Android
    引用
    Response设置响应数据,重定向,目录问题,字节流,字符流
    [附源码]计算机毕业设计JAVA闲置物品线上交易系统
    Apache POl
  • 原文地址:https://blog.csdn.net/u012967763/article/details/126456228