Simple queue algorithm

This is not a request for a queue algorithm, I know there are many.

I am reading a C # book and it explains the Circular Queue algorithm with sample code. On lines 13, 14 and 15, he explains how to check if the queue is full. However, I cannot understand why the first prerequisite is needed. Can someone show me the situation when it would be necessary?

Here's the class code:

Pastie.org

And my question about this section: (putloc + 1 == getloc)

public bool Put(char ch) {    
    /* Queue is full if either putloc is one less than 
    getloc, or if putloc is at the end of the array 
    and getloc is at the beginning. */
    if (putloc + 1 == getloc || ((putloc == q.Length - 1) && (getloc == 0)))
    {
        return false;
    }

      

+2


source to share


7 replies


The first check runs the next part of the statement in the comments.

putloc is one less than getloc



This check is necessary because your turn is round robin. If you can always assume that the end of the queue was the last element in the array, then the check is unnecessary. In this case though ... the end of the queue could happen in the middle of the array, in which case the queue will be full and you will be hit by that condition.

+6


source


Let's say getloc is 5 and putloc is 4, so you no longer have room to put something. Because if you put something in 5, then you just lost what was there 5, since you haven't read it yet.



+2


source


In a circular queue, whenever you insert something into it, putLoc moves through the array, ending at the end. Whenever you pop something from the queue, getLoc traverses the array and also completes at the end. The queue is full when putLoc is immediately before getLoc.

There are two cases when this can happen. If getLoc has never moved, or turns out to wrap back to the beginning of the array, then it is 0 and the queue is full when putLoc is at the end of the array (next click will cause it to wrap 0). This is the second half of the if statement.

If a pair of values ​​are dequeued, then getLoc can be in the middle of the array. In this case, the queue is not filled when putLoc is at the end of the array, but when it is wrapped and immediately before getLoc. In this case, the first part of the if statement is processed (the part you are asking for).

+2


source


Both of them are actually the same condition. Think of it in terms of modulo equality.

A circular queue, implemented with an array, is populated when the last added element is at location N (modulo length), and the earliest element is at location N + 1 (modulo length). This means that there is a "length" of elements in the queue and there is no room for a new one, so it is full.

There are several ways to code this test, but the method used in the example code is to use the string arithmetic version without using a module.

You can also code it like this:

if ((putloc + 1) % q.length == getloc) {}

and it would be logically the same if getloc

it was correctly constrained between 0 and q.length - 1

.

+1


source


The Queue is full if the                 (((in+1)%queue_length)==out)

Queue is empty if you                 (in==out)

notice that "in" indicates that data is being inserted into the queue, while the queue is out out out out "out".

+1


source


The logic can be better understood in the following form:

int new_putloc = (putloc + 1) % q.Length;
if (new_putloc == getloc) return false;

      

the original code just breaks the above logic down to two scenarios:

  • putloc does not rewind, then new_putloc = putloc + 1
  • putloc rewinds, then put_loc = q.Length-1
0


source


The left half of the expression is the main one, which works for almost all scenarios, and the right half is for a unique edge, where putloc is the end of the queue and getloc is the beginning of the queue. When putloc is 4 and getloc is 5, the left side is true, but when the queue is 10 and putloc is 9 and getloc is 0, the right side is true.

0


source







All Articles