Sorting: Bubble sort
•
BUBBLE SORT (DATA, N)
1. Repeat steps 2 and 3 for K = 1 to N – 1
2. Set PTR := 1 [Initializes pass pointer PTR]
3. Repeat while PTR ≤ N – K: [Executes pass.]
(a) if DATA[PTR] > DATA[PTR + 1], then:
interchange DATA[PTR] and DATA[PTR + 1]
[End of if structure]
(b) Set PTR := PTR + 1
[End of inner loop]
Bubble sort: Implementation
Starting with the first item, assume that it is
the largest
Compare it with the second item:
– If the first is larger, swap the two,
– Otherwise, assume that the second item is the
largest
Continue up the array, either swapping or
redefining the largest item
Bubble sort: Implementation
After one pass, the largest item must be
the last in the list
Start at the front again:
– the second pass will bring the second largest
element into the second last position
Repeat
n
– 1
times, after which, all entries
Bubble sort: Example
Consider the unsorted array
to the right
We start with the element in
the first location, and move
forward:
– if the current and next items are
in order, continue with the next
item, otherwise
– swap the two entries
Bubble sort: Example
After one loop, the largest
element is in the last
location
Bubble sort: Example
Now the two largest elements
are at the end
– Repeat again
Bubble sort: Example
Bubble sort: Example
Finally, we swap the last
two entries to order them
– At this point, we have a
sorted array
Searching
•
Searching refers to the operation of finding
the location of an item in linear array.
–
If item is found, then the search is successful
Searching: a basic algorithm
•
LINEAR(DATA, N, ITEM, LOC)
1. [Insert ITEM at the end of DATA]
Set DATA[N +
1] = ITEM
2. [Initialize counter] Set LOC: = 1
3. [Search for item]
o
Repeat while DATA[LOC] ≠ ITEM
o
Set LOC := LOC + 1
o
[End of loop]
4. [Successful?] If LOC = N + 1, then Set LOC:=0
5. Exit
Searching: Binary Search
•
Data is sorted in increasing order.
•
Extremely efficient algorithm.
•
This algorithm works as follows:
•
During each stage of our algorithm, our
Searching: Binary Search
•
BINARY (DATA, LB, UB, ITEM, LOC)
1. [Initialize segment variables]
–
Set BEG = LB, END = UB and
MID = INT((BEG + END)/2)
2. Repeat steps 3 and 4 while BEG ≤ END and DATA[MID] ≠ITEM
3. if ITEM < DATA[MID], then
Set END = MID – 1
4. Else
Set BEG = MID + 1
[End of if structure]
Set MID = INT ((BEG + END)/2)
[End of step 2 loop]
5. if DATA[MID] = ITEM, then:
Set LOC = MID
else
Set LOC = NULL
[End of if structure]
7. Exit
Example: Binary Search
1
0
1
2
3
4
5
6
7
8
9
10
11
12
5
15
19
25
27
29
31
33
45
55
88
100
middle of the array
compare a[6] and 19
19 is smaller than 29 so the next
search will use the lower half of the
array
Example: Binary Search Pass 2
1
0
1
2
3
4
5
5
15
19
25
27
search key = 19
use this as the middle of the array
Compare a[2] with 19
15 is smaller than 19 so use the top
half for the next pass
a
Example: Binary Search Pass 3
3
4
5
25
27
search key = 19
use this as the middle of the array
Compare a[4] with 19
25 is bigger than 19 so use the bottom
half
a
Example: Binary Search Pass 4
3
search key = 19
use this as the middle of the array
Compare a[3] with 19
Found!!
a
19
Multi-dimensional array
•
The arrays whose elements are accessed by
more than one subscript are termed as
multidimensional arrays.
•
A two dimensional m × n array A is a collection
Example: Matrix Multiplication
o
MATMUL(A, B, C, M, P, N)
1. Repeat steps 2 to 4 for I = 1 to M:
2. Repeat steps 3 and 4 for J = 1 to N:
3. Set C[I, J] = 0
4. Repeat for K = 1 to P:
•
C[I, J] = C[I, J] + A[I, K] * B[K, J]
[End of inner loop]
[End of step 2 middle loop]
[End of step 1 outer loop]
5. Exit
Applications of Stack:
The stack data structure is exceptionally straight-forward. Due to its simplicity, the goal
in any engineering problem is to attempt to formulate a solution that makes use of a
stack. Examples of applications include:
1) Parsing code, including:
(a) a. HTML and XML, and
(b) Matching parentheses in C++,
2) Allocating memory for function calls,
3) Evaluating reverse-Polish expressions,
4) Tracking undo and redo operations in applications (going forward and back in a
web browser),
5) Assembly language, and
6) Robert’s Rules of Order.
Robert’s Rules of Order:
This is only for those students interested in politics. Given a deliberative assembly, a
group of people who are meeting to discuss and debate a particular topic, it is necessary
to keep some form of order. Robert’s Rules is a simplification of Parliamentary Rules
used in the legislatures in Canada, the United Kingdom, and the United States. It is also
quite reasonable as a guide for smaller organizations. This book, while written in the
1876, essentially uses a stack to keep track of the debate. There motions that can be
made, and the motions are given precedence. For the assembly to begin discussing a
motion, the motion must be pushed onto the top of an empty stack. The rules are very
simple:
1. You are only allowed to discuss whatever is currently on top of the stack, and
2. For almost all motions, you can only pop a motion off the stack is to vote on it.
For example, someone in EngSoc could make the main motion that “EngSoc should
spend $2,500 on a new computer.” That motion would be placed on the stack. Anyone
who wishes to speak out, either for or against it, may do so, regulated by a meeting
chair. One motion of higher precedence is amending the main motion. Another student
might make the motion “I motion that we amend the main motion to read that ‘EngSoc
should spend $1,500 on a new computer.’” At this point, the amendment is placed onto
the stack. The only issue that may be discussed is the validity of the amendment. If a
person was to get up and speak against the idea of even buying a computer in the first
place, the chair of the meeting should rule that person out of order; that is, they are
discussing a motion that is not currently at the top of the stack. The only pop the motion
to amend is to vote on it. If the motion to amend passes, the main motion is amended
and the discussion continues on the amended main motion. If the motion to amend fails,
the discussion returns to a discussion over the original main motion. By using a stack,
Robert’s Rules of Order allows everyone to understand what is currently being discussed
and it keeps members from straying too far from the point at hand.
http://www.tutorialspoint.com/data_structures_algorithms/stack_algorithm.htm Copyright © tutorialspoint.com
DATA STRUCTURE - STACK
DATA STRUCTURE - STACK
A stack is an abstract data type ADT, commonly used in most programming languages. It is named stack as it behaves like a real-world stack, for example − deck of cards or pile of plates etc.
A real-world stack allows operations at one end only. For example, we can place or remove a card or plate from top of the stack only. Likewise, Stack ADT allows all data operations at one end only. At any given time, We can only access the top element of a stack.
This feature makes it LIFO data structure. LIFO stands for Last-in-first-out. Here, the element which is placed insertedoradded last, is accessed first. In stack terminology, insertion operation is called PUSH operation and removal operation is called POP operation.
Stack Representation
Below given diagram tries to depict a stack and its operations −
A stack can be implemented by means of Array, Structure, Pointer and Linked-List. Stack can either be a fixed size one or it may have a sense of dynamic resizing. Here, we are going to implement stack using arrays which makes it a fixed size stack implementation.
Basic Operations
Stack operations may involve initializing the stack, using it and then de-initializing it. Apart from these basic stuffs, a stack is used for the following two primary operations −
push − pushing storing an element on the stack.
pop − removing accessing an element from the stack.
When data is PUSHed onto stack.
following functionality is added to stacks −
peek − get the top data element of the stack, without removing it.
isFull − check if stack is full.
isEmpty − check if stack is empty.
At all times, we maintain a pointer to the last PUSHed data on the stack. As this pointer always represents the top of the stack, hence named top. The top pointer provides top value of the stack without actually removing it.
First we should learn about procedures to support stack functions −
peek
Algorithm of peek function −
begin procedure peek return stack[top]
end procedure
Implementation of peek function in C programming language −
int peek() {
return stack[top]; }
isfull
Algorithm of isfull function −
begin procedure isfull if top equals to MAXSIZE return true
else
return false
endif
end procedure
Implementation of isfull function in C programming language −
bool isfull() {
if(top == MAXSIZE) return true; else
return false; }
isempty
Algorithm of isempty function −
begin procedure isempty if top less than 1 return true
else
return false
end procedure
Implementation of isempty function in C programming language is slightly different. We initialize top at -1, as index in array starts from 0. So we check if top is below zero or -1 to determine if stack is empty. Here's the code −
bool isempty() { if(top == -1) return true; else
return false; }
PUSH Operation
The process of putting a new data element onto stack is known as PUSH Operation. Push operation involves series of steps −
Step 1 − Check if stack is full.
Step 2 − If stack is full, produce error and exit.
Step 3 − If stack is not full, increment top to point next empty space.
Step 4 − Add data element to the stack location, where top is pointing.
Step 5 − return success.
if linked-list is used to implement stack, then in step 3, we need to allocate space dynamically.
Algorithm for PUSH operation
A simple algorithm for Push operation can be derived as follows −
begin procedure push: stack, data if stack is full
return null
endif
top ← top + 1
stack[top] ← data
end procedure
void push(int data) { if(!isFull()) { top = top + 1; stack[top] = data; }else {
printf("Could not insert data, Stack is full.\n"); }
}
Pop Operation
Accessing the content while removing it from stack, is known as pop operation. In array implementation of pop operation, data element is not actually removed, instead top is
decremented to a lower position in stack to point to next value. But in linked-list implementation, pop actually removes data element and deallocates memory space.
A POP operation may involve the following steps −
Step 1 − Check if stack is empty.
Step 2 − If stack is empty, produce error and exit.
Step 3 − If stack is not empty, access the data element at which top is pointing.
Step 4 − Decrease the value of top by 1.
Step 5 − return success.
Algorithm for POP operation
A simple algorithm for Pop operation can be derived as follows −
begin procedure pop: stack if stack is empty
return null
endif
data ← stack[top]
top ← top - 1
return data
end procedure
Implementation of this algorithm in C, is shown below −
if(!isempty()) { data = stack[top]; top = top - 1; return data; }else {
printf("Could not retrieve data, Stack is empty.\n"); }
}
For a complete stack program in C programming language, please click here.
http://www.tutorialspoint.com/data_structures_algorithms/expression_parsing.htm Copyright © tutorialspoint.com
DATA STRUCTURE - EXPRESSION PARSING
The way to write arithmetic expression is known as notation. An arithmetic expression can be written in three different but equivalent notations, i.e., without changing the essence or output of expression. These notations are −
Infix Notation
Prefix Notation
Postfix Notation
These notations are named as how they use operator in expression. We shall learn the same here in this chapter.
Infix Notation
We write expression in infix notation, e.g. a-b+c, where operators are used in-between operands. It is easy for us humans to read, write and speak in infix notation but the same does not go well with computing devices. An algorithm to process infix notation could be difficult and costly in terms of time and space consumption.
Prefix Notation
In this notation, operator is prefixed to operands, i.e. operator is written ahead of operands. For example +ab. This is equivalent to its infix notation a+b. Prefix notation is also known as Polish Notation.
Postfix Notation
This notation style is known as Reversed Polish Notation. In this notation style, operator is postfixed to the operands i.e., operator is written after the operands. For example ab+. This is equivalent to its infix notation a+b.
The below table briefly tries to show difference in all three notations −
S.n. Infix Notation Prefix Notation Postfix Notation
1 a + b + a b a b +
2 (a + b) * c * + a b c a b + c *
3 a * (b + c) * a + b c a b c + *
4 a / b + c / d + / a b / c d a b / c d / +
5 (a + b) * (c + d) * + a b + c d a b + c d + *
6 ((a + b) * c) - d - * + a b c d a b + c * d
-Parsing Expressions
As we have discussed, it is not very efficient way to design an algorithm or program to parse infix notations. Instead, these infix notations are first converted into either postfix or prefix notations and then computated.
P olish
Reverse
−
P olish
Data Structures and Algorithms Parsing Expres... http://www.tutorialspoint.com/cgi-bin/printpage.cgi
To parse any arithmetic expression, we need to take care of operator precedence and associativity also.
Precedence
When an operand is in between two different operator, which operator will take the operand first, is decided by the precedence of an operator over others. For example −
As multiplication operation has precedence over addition, b * c will be evaluated firs. A table of operator precedence is provided later.
Associativity
Associativity describes the rule where operators with same precedence appear in an expression. For example, in expression a+b−c, both + and − has same precedence, then which part of expression will be evaluated first, is
determined by associativity of those operators. Here, both + and − are left associative, so the expression will be evaluated as (a+b)−c.
Precedence and associativity, determines the order of evaluation of an expression. An operator precedence and associativity table is given below −
S.n. Operator Precedence Associativity
1 Esponentiation ^ Highest Right Associative
2 Multiplication ( * ) & Division ( / ) Second Highest Left Associative
3 Addition ( + ) & Subtraction ( − ) Lowest Left Associative
The above table shows the default behavior of operators. At any point of time in expression evaluation, the order can be altered by using parenthesis. For example −
In a+b*c, the expression part b*c will be evaluated first, as multiplication as precedence over addition. We here use parenthesis to make a+b be evaluated first, like (a+b)*c.
Postfix Evaluation Algorithm
We shall now look at the algorithm on how to evaluate postfix notation −
Step 1 − scan the expression from left to right Step 2 − if it is an operand push it to stack
Step 3 − if it is an operator pull operand from stack and perform operation Step 4 − store the output of step 3, back to stack
Step 5 − scan the expression until all operands are consumed Step 6 − pop the stack and perform operation
To see the implementation in C programming language, please click here.
highesttolowest
Data Structures and Algorithms Parsing Expres... http://www.tutorialspoint.com/cgi-bin/printpage.cgi
Stack: Postfix Operation
•
Q: 5 * ( 6 + 2 ) – 12 / 4
•
P :
5 , 6 , 2 , + , * , 12 , 4 , / , - , )
Symbol Scanned
STACK
1.
5
5
2.
6
5,6
3.
2
5,6,2
4.
+
5,8
5.
*
40
6.
12
40,12
7.
4
40, 12, 4
8.
/
40, 3
9.
-
37
Stacks: Transferring infix into postfix
o
POLISH (Q, P)
1.
PUSH “(” onto STACK, and add “)” to the end of Q
2.
Scan Q from left to right and repeat step 3 to step 6 for each element
of Q until the STACK is empty.
3.
If an operands is encountered, add it to P
4.
If a left parenthesis is encountered, push it onto STACK
5.
If an operator X is encountered then:
a)
Repeatedly POP from STACK and add to P each operator (on
the top of STACK) which has the same precedence as or higher
precedence than X
b)
Add X to STACK
[END of IF Structure]
6.
If a right parenthesis is encountered then:
a)
Repeatedly POP from STACK and add to P each operator (on
the top of STACK) until a left parenthesis is encountered.
b)
Remove the left parenthesis
[END of IF Structure]
[END of STEP 2 loop]
7.
EXIT
Stack: Example
Q:
A + ( B * C - ( D / E F ) * G ) * H )
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Symbol
STACK Expression P
(1)
A
(
A
(2)
+
( +
A
(3)
(
( + (
A
(4)
B
( + (
A B
(5)
*
( + ( *
A B
(6)
C
( + ( * A B C
(7)
-
( + ( - A B C *
(8)
(
( + ( - ( A B C *
(9)
D
( + ( - ( A B C * D
(10) /
( + ( - ( / A B C * D
Stack: Example
Symbol
STACK Expression P
(12)
( + ( - ( / A B C * D E
(13) F
( + ( - ( / A B C * D E F
(14) )
( + ( -
A B C * D E F /
(15) *
( + ( - * A B C * D E F /
(16) G
( + ( - * A B C * D E F / G
(17) )
( +
A B C * D E F / G * -
(18) *
( + *
A B C * D E F / G * -
(19) H
( + *
A B C * D E F / G * - H
(20) )
A B C * D E F / G * - H * +
P: A B C * D E F / G * - H * +
Recursion:
Recursion is a technique to divide the problem into subproblems of the same type. Let
us see an example.
Calculation of factorial
Factorial of n
(
denoted
n!)
is a product of integer numbers from 1 to n. For instance, 5! =
1 * 2 * 3 * 4 * 5 = 120.
Recursion is one of techniques to calculate factorial. Indeed, 5! = 4! * 5. To calculate
factorial of
n
, we should calculate it for
(n-1)
. To calculate factorial of
(n-1)
algorithm
should find
(n-2)!
and so on. But described process will last infinitely, because no base
case has been defined yet.
Base case
is a condition, when recursion should stop. In the
factorial example, a base case is
n = 1,
for which the result is known.
C++ code snippet
int factorial(int n) { if (n <= 1) return 1; else
return n * factorial(n - 1); }
Advantages and drawbacks of recursion
Main
advantage
of recursion is
programming simplicity
. When using recursion,
Quick Sort: An Stacks Application
•
Quick Sort works on Divide and Conquer Rule
•
Quick Sort Strategy is to Divide a List or Set into Two
Sub-Lists or Sub-Sets.
•
Pick an Element, Called a Pivot, from the List.
•
Reorder the List so that all Elements which are Less
than the Pivot come Before the Pivot and so that All
Elements Greater than the Pivot come After it. After
this Partitioning, the Pivot is in its Final Position. This is
called the Partition operation.
•
Recursively Sort the Sub-List of Lesser Elements and
the Sub-List of Greater Elements.
Quicksort
For example, given
we can select the middle entry, 44, and sort the
remaining entries into two groups, those less than 44
and those greater than 44:
Notice that 44 is now in the correct location if the list
was sorted
– Proceed by applying the algorithm to the first six and last
eight entries
80 38 95 84 66 10 79
44
26 87 96 12 43 81
3
http://www.tutorialspoint.com/data_structures_algorithms/dsa_queue.htm Copyright © tutorialspoint.com
DATA STRUCTURE - QUEUE
DATA STRUCTURE - QUEUE
Queue is an abstract data structure, somewhat similar to stack. In contrast to stack, queue is opened at both end. One end is always used to insert data enqueue and the other is used to remove data dequeue. Queue follows First-In-First-Out methodology, i.e., the data item stored first will be accessed first.
A real world example of queue can be a single-lane one-way road, where the vehicle enters first, exits first. More real-world example can be seen as queues at ticket windows & bus-stops.
Queue Representation
As we now understand that in queue, we access both ends for different reasons, a diagram given below tries to explain queue representation as data structure −
Same as stack, queue can also be implemented using Array, Linked-list, Pointer and Structures. For the sake of simplicity we shall implement queue using one-dimensional array.
Basic Operations
Queue operations may involve initializing or defining the queue, utilizing it and then completing erasing it from memory. Here we shall try to understand basic operations associated with queues −
enqueue − add store an item to the queue.
dequeue − remove access an item from the queue.
Few more functions are required to make above mentioned queue operation efficient. These are −
peek − get the element at front of the queue without removing it.
isfull − checks if queue is full.
isempty − checks if queue is empty.
In queue, we always dequeue oraccess data, pointed by front pointer and while enqueing orstoring data in queue we take help of rear pointer.
peek
Like stacks, this function helps to see the data at the front of the queue. Algorithm of peek function −
begin procedure peek return queue[front]
end procedure
Implementation of peek function in C programming language −
int peek() {
return queue[front]; }
isfull
As we are using single dimension array to implement queue, we just check for the rear pointer to reach at MAXSIZE to determine that queue is full. In case we maintain queue in a circular linked-list, the algorithm will differ. Algorithm of isfull function −
begin procedure isfull
if rear equals to MAXSIZE return true
else
return false
endif
end procedure
Implementation of isfull function in C programming language −
bool isfull() {
if(rear == MAXSIZE - 1) return true;
else
return false; }
isempty
Algorithm of isempty function −
begin procedure isempty
if front is less than MIN OR front is greater than rear return true
else
return false
endif
end procedure
If value of front is less than MIN or 0, it tells that queue is not yet initialized, hence empty.
Here's the C programming code −
bool isempty() {
return false; }
Enqueue Operation
As queue maintains two data pointers, front and rear, its operations are comparatively more difficult to implement than stack.
The following steps should be taken to enqueue insert data into a queue −
Step 1 − Check if queue is full.
Step 2 − If queue is full, produce overflow error and exit.
Step 3 − If queue is not full, increment rear pointer to point next empty space.
Step 4 − Add data element to the queue location, where rear is pointing.
Step 5 − return success.
Sometimes, we also check that if queue is initialized or not to handle any unforeseen situations.
Algorithm for enqueue operation
procedure enqueue(data) if queue is full
return overflow endif
rear ← rear + 1
queue[rear] ← data
return true
end procedure
Implementation of enqueue in C programming language −
int enqueue(int data) if(isfull())
return 0;
return 1;
end procedure
Dequeue Operation
Accessing data from queue is a process of two tasks − access the data where front is pointing and remove the data after access. The following steps are taken to perform dequeue operation −
Step 1 − Check if queue is empty.
Step 2 − If queue is empty, produce underflow error and exit.
Step 3 − If queue is not empty, access data where front is pointing.
Step 3 − Increment front pointer to point next available data element.
Step 5 − return success.
Algorithm for dequeue operation −
procedure dequeue if queue is empty return underflow end if
data = queue[front] front ← front - 1
return true end procedure
Implementation of dequeue in C programming language −
int dequeue() { if(isempty()) return 0;
int data = queue[front]; front = front + 1;
Implementing a Queue using a
circular
arrayThe circular array (a.k.a. circular buffer) Circular array:
Circular array = a data structure that used a array as if it were
connected end-to-end
Schematically:
This data structure is also known as:
Circular buffer Cyclic buffer Ring buffer
Read and write pointers of a circular array
A circular buffer has 2 "pointers" (or indices):
http://www.mathcs.emory.edu/~cheung/Courses...
Read pointer: (or read position)
Read pointer = the index of the circular array used by a read
operation
Example:
In the above figure, a read operation will return the value 9
in buf[2]
(because the read pointerread = 2)
Read pointer: (or write position)
Write pointer = the index of the circular array used by a write
operation
Example:
In the above figure, a write operation will update the array
elementbuf[7]
(because the write pointerwrite = 7)
Advancing the read and write pointers in a circular array
Fact:
The read and write operations will advance their corresponding
http://www.mathcs.emory.edu/~cheung/Courses...
pointers
(Because you don't want the read and write operations to read/write the
same array element over and over again....)
The read/write pointers in the following circular array:
will advance in the following manner:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, .... and so on...
because the indices will wrap around:
http://www.mathcs.emory.edu/~cheung/Courses...
It is very easy to increase an index in a wrap around manner:
index = (index + 1) % N
where N = the number of indices
Example:
read = (read + 1) % 4 // will increase read as:
// 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, ...
Read and write operations on a circular array
The read operation on a circular array is as follows:
DataType read() {
DataType r; // Variable used to save the return value
r = buf[read]; // Save return value
read = (read+1)%(buf.length); // Advance the read pointer
return r; }
The write operation on a circular array is as follows:
void write(DataType x) {
buf[write] = x; // Store x in buf at write pointer
write = (write+1)%(buf.length); // Advance the write pointer
}
Representing an empty circular buffer
To discoverhow to represent an empty circular buffer:
Let's find out how the informationchanges when we read data from a
circular buffer first....
The following diagram depicts a circular buffer (array) with 3 data items:
http://www.mathcs.emory.edu/~cheung/Courses...
After readingone data item, the circular buffer (array) will contain 2 data items:
After readingtwo more data item, the circular buffer (array) will become empty:
http://www.mathcs.emory.edu/~cheung/Courses...
Therefore, a circular array (buffer) is empty if:
read pointer == write pointer
Representing an full circular buffer
To discoverhow to represent an empty circular buffer:
Let's find out how the informationchanges when we write data into a
circular buffer first....
The following diagram depicts a circular buffer (array) with 2 empty slots:
http://www.mathcs.emory.edu/~cheung/Courses...
After writingone data item, the circular buffer (array) will contain 1 empty slot:
After writinganother data item, the circular buffer (array) will become full:
http://www.mathcs.emory.edu/~cheung/Courses...
Therefore, a circular array (buffer) is full if:
read pointer == write pointer
Trouble:
The conditionread pointer == write pointer can indicate:
an empty buffer, or
a full buffer
Breaking the ambiguity
Traditionally, the following trick is used to to break the ambiguity:
We assume that the circular buffer is full when:
There is one empty slot left in the circular buffer:
Example:
http://www.mathcs.emory.edu/~cheung/Courses...
In other words, we use the following test to check if the circular buffer is full:
read pointer == ( write pointer + 1 ) % (buf.length)
Implementing a Queue using a circular array
Just like the Stack, we can implement a Queue using different data structures.
You just saw the implementation of the queue using a list
The implementation of operations of a queue using a circular array is as follows:
enqueue( x ) // This is writing in a circular buffer (See: click here) {
if ( read == ( write + 1 ) % (buf.length) ) {
throw new Exception("Queue is full"); }
buf[write] = x; // Store x in buf at write pointer
write = (write+1)%(buf.length); // Advance the write pointer
}
DataType dequeue() // This is reading in a circular buffer (See: click here) {
DataType r; // Variable used to save the return value if ( read == write )
http://www.mathcs.emory.edu/~cheung/Courses...
{
throw new Exception("Queue is empty"); }
r = buf[read]; // Save return value
read = (read+1)%(buf.length); // Advance the read pointer
return r; }
In Java:
public class ArrayQueue implements Queue
{
/* ========================================== Node "inner class"
========================================== */ public class Node
{
double value; Node next;
public Node( double x ) {
value = x; next = null; }
public String toString() {
return "" + value; }
}
public double[] buf; // Circular buffer
public int read, write; // read and write pointers
// Constructor
public ArrayQueue(int size)
{
buf = new double[size]; // Create array for circular buffer
read = 0; // Initialized read & write pointers
write = 0;
}
/* ==================================================== enqueue(x ):
==================================================== */ public void enqueue( double x ) throws Exception
{
if ( read == ( write + 1 ) % (buf.length) ) // Full... {
throw new Exception("Queue is full"); }
buf[write] = x; // Store x in buf at write pointer
write = (write+1)%(buf.length); // Advance the write pointer
}
/* ==================================================== dequeue():
==================================================== */ public double dequeue( ) throws Exception
{
double r; // Variable used to save the return value
if ( read == write )
http://www.mathcs.emory.edu/~cheung/Courses...
{
throw new Exception("Queue is empty"); }
r = buf[read]; // Save return value
read = (read+1)%(buf.length); // Advance the read pointer
return r;
} }
Example Program: (Demo above code)
The Queue interface Prog file: click here
The ArrayQueue implementation Prog file: click here
The test Prog file: click here
How to run the program:
Right click on link(s) and save in a scratch directory
To compile: javac testProg.java
To run: java testProg
Empty and full conditions
The following test program can be used to trigger a queue full error:
public static void main( String[] args ) throws Exception {
Queue myQ = new ArrayQueue(3); double x;
myQ.enqueue(1.0);
System.out.println("enqueue(1.0): " + "myQ = " + myQ); myQ.enqueue(2.0);
System.out.println("enqueue(2.0): " + "myQ = " + myQ); myQ.enqueue(3.0); // <--- will cause exception
System.out.println("enqueue(3.0): " + "myQ = " + myQ); }
The following test program can be used to trigger a queue empty error:
public static void main( String[] args ) throws Exception {
Queue myQ = new ArrayQueue(10); double x;
x = myQ.dequeue(); // <--- will cause exception
}
http://www.mathcs.emory.edu/~cheung/Courses...