It's been a long time since I had to write queue handling, (especially since they are built into .NET) but the main things I remember made it a lot easier were:
1) Have an "input" indicator, and and "output" indicator.
2) When "input" == "output", the queue is empty. Advanced version can have a count, but it isn't necessary.
3) Otherwise, keep input and output separate.
public class MyQueue<T>
{
private T[] data;
private int input = 0;
private int output = 0;
public MyQueue(int size)
{
data = new T[size];
}
public void Enqueue(T item)
{
data[input++] = item;
if (input >= data.Length)
{
input = 0;
}
}
public T Dequeue()
{
if (input == output)
{
throw new ApplicationException("Buffer underrun");
}
T result = data[output++];
if (output >= data.Length)
{
output = 0;
}
return result;
}
public bool IsEmpty()
{
return input == output;
}
}
Notice this doesn't check for overrun!