Definition
An implementation of a limited collection with specified a fixed numbers of items in which only the earliest added item may be accessed using an array.
Basic operations are add (to the tail; or the last item of list) or enqueue; and throw (from the head; or the first item of a list) or dequeue. Also known as “first-in, first-out” or FIFO. And list is a collection of items accessible one after another beginning at the head and ending at the tail.
![]()
Above visually shows that the queue has no real end and it can loop around the queue. However, since memory is never physically created as a ring, a linear representation is generally used as is done below.
Illustrations
1. A circular queue first starts empty and of some predefined length. For example, circular queue with length 7.
![]()
2. Enqueue the defined circular queue until 7 times, then it is completely full.
![]()
3. The head is first element; tail is last element.
4. When dequeue was execute, the first element “6” will throw; and head index will increment.
5. Head index will increment and back to first when equals with defined length of circular queue.
Implementations (with C# .NET 3.5)
Defined length of circular queue directly when instantiate the object.
1: /// <summary>Default constructor.</summary>2: /// <exception cref="System.ArgumentOutOfRangeException"></exception>3: /// <param name="capacity">The number of elements that the new list can initially store.</param>4: public clsCircularQueue(int capacity)5: {6: if (capacity < 0)7: throw new ArgumentOutOfRangeException("capacity", "Cannot create an array with a negative size.");8:9: //...other code.10: }
Enqueue implementation or add member/ element.
1: /// <summary>Adds the integer value to the tail of Circular Queue.</summary>2: /// <exception cref="System.IndexOutOfRangeException"></exception>3: /// <param name="value"></param>4: public void Enqueue(int value)5: {6: if (this.Length == 0)7: throw new IndexOutOfRangeException();8:9: if (this.tail >= this.items.Length)10: this.tail = 0;11:12: this.items[this.tail] = value;13: this.tail++;14: }
Dequeue implementation or throw member/ element.
1: /// <summary>Returns the integer value at the head positon of Circular Queue.</summary>2: /// <exception cref="System.MissingMemberException"></exception>3: /// <returns></returns>4: public int Dequeue()5: {6: int? result = this.items[this.head];7:8: if (!result.HasValue)9: throw new MissingMemberException();10:11: this.head++;12: if (this.head >= this.Length)13: this.head = 0;14:15: return result.Value;16: }
Because that class was inherit from IEnumerable<T>, so we must implemented the IEnumerator<T>. In this case, we implemented own IEnumerator<T>, called clsEnumeratorCircularQueue.
The MoveNext implementation of that custom IEnumerator.
1: /// <summary>Advances the enumerator to the next element of the collection.</summary>2: /// <returns></returns>3: public bool MoveNext()4: {5: try6: {7: this.counter++;8: if (counter > this.circularQueue.Length)9: {10: this.current = null;11: this.counter = 0;12: return false;13: }14:15: this.current = this.circularQueue.Dequeue();16: return true;17: }18: catch19: {20: return false;21: }22: }
Lets test!
1: ...2: int capacity = 8;3: Console.WriteLine("Capacity: " + capacity);4: clsCircularQueue circularQueue = new clsCircularQueue(capacity);5: for (int i = 1; i <= 10; i++)6: circularQueue.Enqueue(i);7:8: Console.WriteLine("Iteration with foreach.");9: foreach (int value in circularQueue)10: Console.Write(value + " | ");11: ...
The result:
The complete source-code:
1: using System;2: using System.Collections.Generic;3:4: namespace Ronald.CircularQueue5: {6: /// <summary>Represent circular queue.</summary>7: public sealed class clsCircularQueue : IEnumerable<Int32>8: {9: #region Declarations10:11: private readonly int?[] items = null;12: private int head = 0;13: private int tail = 0;14:15: #endregion16:17: #region Constructors18:19: /// <summary>Private constructor.</summary>20: /// <exception cref="System.NotSupportedException"></exception>21: private clsCircularQueue()22: {23: throw new NotSupportedException("Use constructor with parameter that pass the capacity.");24: }25:26: /// <summary>Default constructor.</summary>27: /// <exception cref="System.ArgumentOutOfRangeException"></exception>28: /// <param name="capacity">The number of elements that the new list can initially store.</param>29: public clsCircularQueue(int capacity)30: {31: if (capacity < 0)32: throw new ArgumentOutOfRangeException("capacity", "Cannot create an array with a negative size.");33:34: this.items = new int?[capacity];35: }36:37: #endregion38:39: /// <summary>Gets a 32-bit integer that represents40: /// the total number of elements in all the dimensions of the System.Array.</summary>41: public int Length { get { return this.items.Length; } }42:43: /// <summary>Adds the integer value to the tail of Circular Queue.</summary>44: /// <exception cref="System.IndexOutOfRangeException"></exception>45: /// <param name="value"></param>46: public void Enqueue(int value)47: {48: if (this.Length == 0)49: throw new IndexOutOfRangeException();50:51: if (this.tail >= this.items.Length)52: this.tail = 0;53:54: this.items[this.tail] = value;55: this.tail++;56: }57:58: /// <summary>Returns the integer value at the head positon of Circular Queue.</summary>59: /// <exception cref="System.MissingMemberException"></exception>60: /// <returns></returns>61: public int Dequeue()62: {63: int? result = this.items[this.head];64:65: if (!result.HasValue)66: throw new MissingMemberException();67:68: this.head++;69: if (this.head >= this.Length)70: this.head = 0;71:72: return result.Value;73: }74:75: #region IEnumerable<Int32> Members76:77: /// <summary>Returns an enumerator that iterates through the Circular Queue.</summary>78: /// <returns></returns>79: public IEnumerator<Int32> GetEnumerator()80: {81: return new clsEnumeratorCircularQueue(this);82: }83:84: #endregion85:86: #region IEnumerable Members87:88: /// <summary>89: ///90: /// </summary>91: /// <returns></returns>92: System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()93: {94: throw new Exception("The method or operation is not implemented.");95: }96:97: #endregion98:99: /// <summary>Supports a circular iteration over a collection.</summary>100: public sealed class clsEnumeratorCircularQueue : IEnumerator<Int32>101: {102: #region Declarations103:104: private readonly clsCircularQueue circularQueue = null;105: private int? current = null;106: private int counter = 0;107:108: #endregion109:110: #region Constructors111:112: /// <summary>Private constructor.</summary>113: /// <exception cref="System.NotSupportedException"></exception>114: private clsEnumeratorCircularQueue()115: {116: throw new NotSupportedException("Use constructor with parameter that pass the capacity.");117: }118:119: /// <summary>Default constructor.</summary>120: /// <exception cref="System.ArgumentNullException"></exception>121: /// <param name="circularQueue"></param>122: public clsEnumeratorCircularQueue(clsCircularQueue circularQueue)123: {124: if (circularQueue == null)125: throw new ArgumentNullException("circularQueue");126:127: this.circularQueue = circularQueue;128: this.current = this.circularQueue.items[this.circularQueue.head];129: }130:131: #endregion132:133: #region IEnumerator<Int32> Members134:135: /// <summary>Gets the element in the collection at136: /// the current position of the enumerator.</summary>137: /// <exception cref="System.MissingMemberException"></exception>138: public int Current139: {140: get141: {142: if (!this.current.HasValue)143: {144: this.counter = 0;145: throw new MissingMemberException();146: }147:148: return this.current.Value;149: }150: }151:152: #endregion153:154: #region IDisposable Members155:156: /// <summary>Performs application-defined tasks associated with157: /// freeing, releasing, or resetting unmanaged resources.</summary>158: public void Dispose()159: { }160:161: #endregion162:163: #region IEnumerator Members164:165: /// <summary>166: ///167: /// </summary>168: object System.Collections.IEnumerator.Current169: {170: get { throw new Exception("The method or operation is not implemented."); }171: }172:173: /// <summary>Advances the enumerator to the next element of the collection.</summary>174: /// <returns></returns>175: public bool MoveNext()176: {177: try178: {179: this.counter++;180: if (counter > this.circularQueue.Length)181: {182: this.current = null;183: this.counter = 0;184: return false;185: }186:187: this.current = this.circularQueue.Dequeue();188: return true;189: }190: catch191: {192: return false;193: }194: }195:196: /// <summary>Sets the enumerator to its initial position,197: /// which is before the first element in the collection.</summary>198: public void Reset()199: {200: this.circularQueue.head = 0;201: this.circularQueue.tail = 0;202: }203:204: #endregion205: }206:207: }208: }209:
References:
http://en.wikipedia.org/wiki/Circular_buffer
http://www.itl.nist.gov/div897/sqg/dads/
No comments:
Post a Comment