算法:基於 RingBuffer 的 Queue 實現

背景

若是基於數組實現隊列,常見的選擇是採用 RingBuffer,不然就須要移動數組元素。數組

RingBuffer

很容易看出 RingBuffer 的思想,這裏就不贅述了。測試

您能夠思考一個問題:圖中表示的場景是一個空隊列?仍是一個滿隊列?答案是:單單維護 _header 和 _tail 還不足以判斷,必須維護一個 _count 計數。this

ArrayQueue

代碼spa

 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 }

測試code

 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 }

備註

真正的基於數組的隊列還須要考慮擴容,通常的策略是:成本的擴容。blog

相關文章
相關標籤/搜索