• 算法:基于 RingBuffer 的 Queue 实现


    背景

    如果基于数组实现队列,常见的选择是采用 RingBuffer,否则就需要移动数组元素。

    RingBuffer

    很容易看出 RingBuffer 的思想,这里就不赘述了。

    您可以思考一个问题:图中表示的场景是一个空队列?还是一个满队列?答案是:单单维护 _header 和 _tail 还不足以判断,必须维护一个 _count 计数。

    ArrayQueue

    代码

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace DataStuctureStudy.Queues
     8 {
     9     public class ArrayQueue<T>
    10     {
    11         private readonly int _maxSize;
    12         private readonly T[] _items;
    13         private int _count = 0;
    14         private int _header = 0;
    15         private int _tail;
    16 
    17         public ArrayQueue(int size)
    18         {
    19             _maxSize = size;
    20             _items = new T[size];
    21             _tail = _maxSize - 1;
    22         }
    23 
    24         public void EnQueue(T item)
    25         {
    26             if (this.IsFull())
    27             {
    28                 throw new InvalidOperationException("队列已满");
    29             }
    30 
    31             if (_tail == _maxSize - 1)
    32             {
    33                 _tail = -1;
    34             }
    35 
    36             _items[++_tail] = item;
    37 
    38             _count++;
    39         }
    40 
    41         public T DeQueue()
    42         {
    43             if (this.IsEmpty())
    44             {
    45                 throw new InvalidOperationException("队列已空");
    46             }
    47 
    48             T item = _items[_header++];
    49 
    50             if (_header == _maxSize)
    51             {
    52                 _header = 0;
    53             }
    54 
    55             _count--;
    56 
    57             return item;
    58         }
    59 
    60         public T Peek()
    61         {
    62             if (this.IsEmpty())
    63             {
    64                 throw new InvalidOperationException("队列已空");
    65             }
    66 
    67             return _items[_header];
    68         }
    69 
    70         public bool IsFull()
    71         {
    72             return _count == _maxSize;
    73         }
    74 
    75         public bool IsEmpty()
    76         {
    77             return _count == 0;
    78         }
    79     }
    80 }

    测试

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace DataStuctureStudy
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             var queue = new Queues.ArrayQueue<int>(5);
    14 
    15             queue.EnQueue(1);
    16             queue.EnQueue(2);
    17             queue.EnQueue(3);
    18             queue.EnQueue(4);
    19             queue.EnQueue(5);
    20             while (!queue.IsEmpty())
    21             {
    22                 Console.WriteLine(queue.DeQueue());
    23             }
    24 
    25             queue.EnQueue(1);
    26             queue.EnQueue(2);
    27             queue.EnQueue(3);
    28             queue.EnQueue(4);
    29             queue.EnQueue(5);
    30             while (!queue.IsEmpty())
    31             {
    32                 Console.WriteLine(queue.DeQueue());
    33             }
    34         }
    35     }
    36 }

    备注

    真正的基于数组的队列还需要考虑扩容,一般的策略是:成本的扩容。

  • 相关阅读:
    django模板语言导入自定html文件内容
    django模板语言中的自定义函数
    ID3决策树
    K近邻算法
    Mini-Batch 、Momentum、Adam算法的实现
    python3安装scrapy教程
    numpy高级应用
    numpy.random随机数生成
    numpy 线性代数
    numpy文件操作
  • 原文地址:https://www.cnblogs.com/happyframework/p/3481697.html
Copyright © 2020-2023  润新知