Click here to Skip to main content
15,881,745 members
Articles / Programming Languages / C#
Tip/Trick

IndexedQueue<T> - A Custom Queue in C#

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
5 Dec 2019MIT1 min read 10.1K   227   9   2
Fills a gap in Microsoft's Queue offering with an alternative allowing efficient indexed access

Introduction

Microsoft provides a Queue<T> class but despite being ordered, it does not provide indexed access to its elements. Since I needed one that allowed efficient access by index, I reimplemented a queue over a growable circular buffer backed by an array. This is similar to how Microsoft's implementation does it. The main difference is mine exposes just a little bit more functionality. This class is highly specialized, but when you need it, you really need it, so I'm providing it here. I use it in my backtracking parsers to back the lookahead buffer.

Note: I originally called this Queue<T> because that's the best name for it, but I changed it to avoid collision with Microsoft's queue. The project name and folder names reflect the old name, but the class and source files have been updated with the new name.

Using the Code

Using the code is exactly like using the code in Microsoft's Queue<T> with the addition of an indexer property. The reason I didn't implement IList<T> is because to implement Insert() is non-trivial and at that point, the container essentially becomes a double-ended queue in functionality, which is a whole different data structure. Eventually, I may post one.

The demo code is pretty self explanatory:

C#
var q = new IndexedQueue<int>(1);
Console.WriteLine("Enqueuing 1..20");
for (var i = 0; i < 20; ++i)
    q.Enqueue(i + 1);

Console.WriteLine("Dequeuing 1..10");
for (var i = 0; i < 10; ++i)
    Console.Write("{0} ",q.Dequeue());
Console.WriteLine();

Console.WriteLine("Enqueuing 21..40 (force array wrap)");
for (var i = 0; i < 20; ++i)
    q.Enqueue(i + 21);

Console.WriteLine("Enumerating");
foreach (var i in q)
    Console.Write("{0} ", i);
Console.WriteLine();

Console.WriteLine("Removing 34 (middle of array)");
(q as System.Collections.Generic.ICollection<int>).Remove(34);

Console.WriteLine("Enumerating");
foreach (var i in q)
    Console.Write("{0} ", i);
Console.WriteLine();

Console.WriteLine("Removing 32 (end of array)");
(q as System.Collections.Generic.ICollection<int>).Remove(32);

Console.WriteLine("Enumerating");
foreach (var i in q)
    Console.Write("{0} ", i);
Console.WriteLine();

Implementing it was fairly straightforward, but removes from the middle (for ICollection<T>) got a little tricky.

Anyway, if you need it, here it is. Most people probably never will, but there you go.

History

  • 12th December, 2019 - Initial submission

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
United States United States
Just a shiny lil monster. Casts spells in C++. Mostly harmless.

Comments and Discussions

 
QuestionWhy not use List<T> Pin
Peter BCKR5-Dec-19 23:48
Peter BCKR5-Dec-19 23:48 
AnswerRe: Why not use List<T> Pin
honey the codewitch6-Dec-19 1:26
mvahoney the codewitch6-Dec-19 1:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.