Причина, по которой очередь заполнена при размере N-1, заключается в том, что в этой простой реализации 'r' представляет индекс следующего свободного элемента, а 'f' представляет следующий элемент для извлечения. Если «f» и «r» равны, очередь пуста, поэтому очередь заполнена, если при увеличении «r» она будет равна «f».
В этой реализации хотя бы один элемент всегда пуст. Это обычно более эффективно, чем добавление дополнительной логики, чтобы дифференцировать случай, когда 'f' и 'r' равны, и очередь заполнена по сравнению со случаем, когда она пуста.
Кстати, в большинстве процессоров функция мода намного дороже, чем при использовании такой логики:
Algorithm enqueue(e):
rNext<---r + 1
if rNext = N
rNext<---0
if rNext = r then
throw a FullQueueException
r<---rNext
Q[r]<---e