AuD
Lecture 'Algorithmen und Datenstrukturen' (code examples)
aud.Queue< T > Class Template Reference

Implementation of AbstractQueue as a (dynamically resized) circular buffer based on array. More...

+ Inheritance diagram for aud.Queue< T >:
+ Collaboration diagram for aud.Queue< T >:

Public Member Functions

 Queue ()
 create empty queue More...
 
 Queue (int capacity)
 create empty queue and reserve storage More...
 
boolean is_empty ()
 Is queue empty? More...
 
front ()
 Get front element of queue. More...
 
dequeue ()
 Remove front element from queue. More...
 
void enqueue (T x)
 Enqueue element at end of queue. More...
 
String toString ()
 Get string representation. More...
 
abstract boolean is_empty ()
 Is queue empty? More...
 
abstract T front ()
 Get front element of queue. More...
 
abstract T dequeue ()
 Remove front element from queue. More...
 
abstract void enqueue (T x)
 Enqueue element at end of queue. More...
 
String toString ()
 

Additional Inherited Members

- Protected Member Functions inherited from aud.adt.AbstractQueue< T >
 AbstractQueue ()
 create empty queue More...
 

Detailed Description

Implementation of AbstractQueue as a (dynamically resized) circular buffer based on array.

Definition at line 11 of file Queue.java.

Constructor & Destructor Documentation

◆ Queue() [1/2]

aud.Queue< T >.Queue ( )

create empty queue

Definition at line 21 of file Queue.java.

21 {
22 this(DEFAULT_SIZE);
23 }

◆ Queue() [2/2]

aud.Queue< T >.Queue ( int  capacity)

create empty queue and reserve storage

Definition at line 27 of file Queue.java.

27 {
28 data_=(T[]) new Object[capacity];
29 head_=tail_=0;
30 }

Member Function Documentation

◆ dequeue()

T aud.Queue< T >.dequeue ( )

Remove front element from queue.

Requires !is_empty().

Exceptions
NoSuchElementException
Returns
removed element

Reimplemented from aud.adt.AbstractQueue< T >.

Reimplemented in aud.example.VerboseQueue< T >.

Definition at line 50 of file Queue.java.

50 {
51 if (is_empty())
52 throw new NoSuchElementException();
53 T obj=data_[head_];
54 data_[head_]=null; // "free" entry (for GC)
55 head_=(head_+1)%data_.length;
56 return obj;
57 }
boolean is_empty()
Is queue empty?
Definition: Queue.java:35

References aud.Queue< T >.is_empty().

Referenced by aud.example.expr.ExpressionTreeTraversal.levelorder(), aud.example.BinaryTreeTraversal.levelorder(), and aud.test.QueueTest.testInvalid_dequeue().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ enqueue()

void aud.Queue< T >.enqueue ( x)

Enqueue element at end of queue.

Parameters
xnew element

Reimplemented from aud.adt.AbstractQueue< T >.

Reimplemented in aud.example.VerboseQueue< T >.

Definition at line 62 of file Queue.java.

62 {
63 int newtail=(tail_+1)%data_.length;
64
65 if (newtail!=head_) {
66 // no "overrun" we just advance an index.
67 data_[tail_]=x;
68 tail_=newtail;
69 }
70 else {
71 //@>queue:enqueue1
72 //System.err.println("enlarge buffer of size "+data_.length);
73
74 // detected "overrun": the new head "hits" tail --
75 // This means the alloacted buffer data is too small!
76
77 // get larger buffer q
78 Queue<T> q=new Queue<T>(data_.length*2);
79
80 // copy data into q
81 while (!is_empty())
82 q.enqueue(dequeue());
83 q.enqueue(x);
84
85 // "steal" state of temporary object q
86 data_=q.data_;
87 head_=q.head_;
88 tail_=q.tail_;
89 assert(head_==0 && tail_<data_.length);
90 }
91 }
T dequeue()
Remove front element from queue.
Definition: Queue.java:50

Referenced by aud.example.expr.ExpressionTreeTraversal.levelorder(), and aud.example.BinaryTreeTraversal.levelorder().

+ Here is the caller graph for this function:

◆ front()

T aud.Queue< T >.front ( )

Get front element of queue.

Requires !is_empty().

Exceptions
NoSuchElementException
Returns
front element

Reimplemented from aud.adt.AbstractQueue< T >.

Definition at line 42 of file Queue.java.

42 {
43 if (is_empty())
44 throw new NoSuchElementException();
45 return data_[head_];
46 }

References aud.Queue< T >.is_empty().

Referenced by aud.test.QueueTest.testInvalid_front().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_empty()

boolean aud.Queue< T >.is_empty ( )

◆ toString()

String aud.Queue< T >.toString ( )

Get string representation.

Impementation note:

This method reads out the queue in reverse order, i.e., we are "going backwards" and shift an index by -1 instead of +1 modulo array length.

The Java expression ab computes the remainder of an integer division and is differs from the mathematical definition of a mod b for negative operands!

The modulo operation is defined as

a mod b := b-floor(a/b)*b

where floor(x) rounds to the greatest integer that is less than or equal to x (i.e., "towards negative infinity").

This is what we want, because

a mod b = (a+k*b) mod b for any integer k (regardless of sign)

For example consider an array of size 3 then position -1 should refer to the last entry

-1 mod 3 = -1+3 mod 3 = 2 mod 3 = 2

Java (and similarly C/C++) defines the remainder operator differently such that the sign is treated "symmetrically" (not rounding towards negative infinity but towards 0):

a%b = (-a%b) for b>=0

For the example, we get

(-1)%3 = 1%3 = 1

which is not what we want as index into the buffer!

We avoid this issue by adding -1+data_.length instead of -1.

Summary:

  • Computing the remainder of an integer division (by an operator) is treated differently in different programming languages.
  • The same is true for the (rounding mode of the) integer division itself. The reason for the "non-mathematical" definition is probably the behavior of the machine instructions (like idiv< on Itel CPUs).
  • Differences show up for negative operands And they can lead to subtle bugs!
  • To be safe, make sure that operands are nonegative!

Reimplemented from aud.adt.AbstractQueue< T >.

Definition at line 152 of file Queue.java.

152 {
153 if (is_empty())
154 return "<";
155
156 String s="";
157
158 int t=(tail_+data_.length-1)%data_.length;
159 for (;;) {
160 s=data_[t]+"<"+s;
161 if (t==head_)
162 break;
163 t=(t+data_.length-1)%data_.length;
164 }
165 return s;
166 }

References aud.Queue< T >.is_empty().

+ Here is the call graph for this function:

The documentation for this class was generated from the following file: