• No results found

Lecture 00 Array Stack Queue

N/A
N/A
Protected

Academic year: 2020

Share "Lecture 00 Array Stack Queue"

Copied!
48
0
0

Loading.... (view fulltext now)

Full text

(1)

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]

(2)

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

(3)

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

(4)

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

(5)

Bubble sort: Example

After one loop, the largest

element is in the last

location

(6)

Bubble sort: Example

Now the two largest elements

are at the end

– Repeat again

(7)

Bubble sort: Example

(8)

Bubble sort: Example

Finally, we swap the last

two entries to order them

– At this point, we have a

sorted array

(9)

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

(10)

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

(11)

Searching: Binary Search

Data is sorted in increasing order.

Extremely efficient algorithm.

This algorithm works as follows:

During each stage of our algorithm, our

(12)

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

(13)

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

(14)

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

(15)

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

(16)

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

(17)

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

(18)

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

(19)

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.

(20)

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.

(21)

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

(22)

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

(23)

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 −

(24)

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.

(25)

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

(26)

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

(27)

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

(28)

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

(29)

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

(30)

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 * +

(31)

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,

(32)

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.

(33)

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

(34)

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.

(35)

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() {

(36)

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;

(37)

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;

(38)

Implementing a Queue using a

circular

array

The 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...

(39)

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...

(40)

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...

(41)

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...

(42)

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...

(43)

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...

(44)

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...

(45)

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...

(46)

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...

(47)

{

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...

(48)

{

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...

References

Related documents

Theories of explanation (such as the deductive-nomological or holistic models) which leave the contrastive structure of explanation unspecified are therefore greatly incomplete

Defendants.. This notice is being given by Order of the Court to individuals who may be members of a class of current and future adult immigration detainees who have or will

10/11/2012 97 STIPULATION WITH PROPOSED ORDER (to extend briefing schedule on motion to dismiss by one week) filed by City of Bristol Pension Fund, City of Omaha Police and

AQUIK: Ambulatory Quality indicators and figures (Germany); CDS: Swiss Conference of the cantonal health directors; CMPR: College of Primary Care Medicine; FMH: Swiss

This study aimed at assessing the proportions and risk factors of poor immune recovery in adult HIV- infected patients on 48 months of HAART attending care and treatment center (CTC)

Despite overall positive perceptions of the referral system, caregivers in three villages reported that health facilities utilised the VHT as a gatekeeper, noting that if they

the claim for payment or reimbursement for the initial evaluation and treatment is for a condition of such a nature that a prudent layperson would have reasonably expected that delay

Not only does Motor Inn of Knoxville take care of your vehicle at an unfortunate time that the body shop is needed, we also offer complete warranty repair service on all General