Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and...

48
©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap. A node is a structure variable or an object with two types of member variables: A data part: one or more member variables appropriate to hold the data in the list, and A next part: a pointer variable to hold the address of the next node in the list. Examples of Nodes Declared as Structure Variables 1. Node to hold an integer value: struct IntegerNode { int value; //data part IntegerNode *next; // next part }; 2. Node to hold the information about a product represented by the following structure type: struct ProductInfo { int prodNum; // to hold a product number double unitPrice; // to hold a product unit price int quantity; // to hold a product quantity }; Can be defined by one of the following structures: struct ProductNode1 { int prodNum; // to hold a product number double unitPrice; // to hold its unit price int quantity; // to hold its quantity ProductNode1 *next; // address of next node }; struct ProductNode2 { ProductInfo product; // a product’s information ProductNode2 *next; // address of next node }; However, structure type ProductNode2 is more suitable than structure type ProductNode1 for lists processing.

Transcript of Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and...

Page 1: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 221

Linked Lists, Stacks, and Queues

Linked Lists

A linked list is a series of connected nodes allocated in the heap.

A node is a structure variable or an object with two types of member variables:

A data part: one or more member variables appropriate to hold the data in the list, and

A next part: a pointer variable to hold the address of the next node in the list.

Examples of Nodes Declared as Structure Variables

1. Node to hold an integer value:

struct IntegerNode

{

int value; //data part

IntegerNode *next; // next part

};

2. Node to hold the information about a product represented by the following structure type:

struct ProductInfo

{

int prodNum; // to hold a product number

double unitPrice; // to hold a product unit price

int quantity; // to hold a product quantity

};

Can be defined by one of the following structures:

struct ProductNode1

{

int prodNum; // to hold a product number

double unitPrice; // to hold its unit price

int quantity; // to hold its quantity

ProductNode1 *next; // address of next node

};

struct ProductNode2

{

ProductInfo product; // a product’s information

ProductNode2 *next; // address of next node

};

However, structure type ProductNode2 is more suitable than structure type ProductNode1 for lists

processing.

Page 2: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 222

Examples of Nodes Declared as Object Instances of a Class

a. Node to hold an integer value:

class IntegerNode

{

public:

int value; //data part

IntegerNode *next; // next part

};

b. Node to hold the information about a product represented by the following structure type:

struct ProductInfo

{

int prodNum; // to hold a product number

double unitPrice; // to hold a product unit price

int quantity; // to hold a product quantity

};

Can be defined by one of the following classes:

class ProductNode1

{

public:

int prodNum; // to hold a product number

double unitPrice; // to hold its unit price

int quantity; // to hold its quantity

ProductNode1 *next; // address of next node

};

class ProductNode2

{

public:

ProductInfo product; // a product’s information

ProductNode2 *next; // address of next node

};

As in the case of structures, class ProductNode2 is more suitable than class ProductNode1 for lists

processing. In general, given a class AClass, we can define a class that can be used to create nodes with

its data members as the data part as follows:

class AClassNode

{

public:

AClass data;

AClassNode *next;

};

This class may also have constructors and other member functions.

Page 3: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 223

Exercise L1

1. Write the definition of a structure and the definition of a class that can be used to create a node with

a double precision value in its data part.

2. The information about a course is represented by the following structure:

struct CourseInfo

{

string courseNum;

int credit;

double gpv;

};

Write the definition of a structure and the definition of a class that can be used to create a node with

this information in its data part.

3. The information about a student is represented by the following structure:

struct StudentInfo

{

string firstName,

lastName;

int idNum;

double gpa;

};

Write the definition of a structure and the definition of a class that can be used to create a node with

this information in its data part.

4. Write the definition of a class that can be used to create nodes with the data part the data members of

the class Date that you defined in exercise O7.

5. Write the definition of a class that can be used to create nodes with the data part the data members of

the class Employee that you defined in exercise O9.

Creating a Linked List

The nodes of a linked list are connected as follows:

1. There is a pointer variable (that is referred to as the head of the list) that holds the address of the

first node in the linked list. It holds NULL when the list is empty.

2. The pointer variable next of the first node holds the address of the second node; that of the

second node holds the address of the third node; . . ., etc.

3. The pointer variable next of the last node holds NULL.

Page 4: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 224

Examples

a. Empty linked list:

NULL

List Head

b. Linked lists with three nodes:

Data

members

Data

members

Data

members NULL

List Head

next next next

Example:

Address: 104 116 134

104

12 116

56 134

35 NULL

List Head

next next next

You create an empty linked list as follows:

1. Define a pointer variable to hold the address of the first node in the linked list: head of the list.

2. Initialize that pointer variable to NULL.

Examples

1. Empty linked list to hold integer values:

IntegerNode *integerListHead ;

integerListHead = NULL;

2. Empty linked lists to hold information about products:

ProductNode1 *productListfirst1 = NULL; or

ProductNode2 *productListfirst2 = NULL;

Page 5: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 225

Basic Operations on Linked Lists

The following table lists some basic operations that can be performed on a linked list:

Operation

Inserting a node at the head of a

linked list.

Inserting a node after a given node in

the linked list.

Insert a node at the end (append) of a

linked list.

Removing the node from the head of

the linked list.

Removing the node after a given

node in the linked list.

Traversing a linked list (for example

to display the data in each node)

Destroying a linked list

We implement the above operations by using a linked list of integer values.

Algorithm to Remove a Node from the Front of a Linked List

The pointer variable discardptr is used to hold the address of the node to be removed from the list.

The algorithm follows:

1. If the list is empty, then stop.

2. Set the pointer variable discardptr to the address of the first node in the list:

discardptr = head;

3. Set the head of the list to the node that follows the node to be removed:

head = discardptr -> next;

4. Release the first node: delete discardptr;

Page 6: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 226

Given the following linked list:

Address: 104 116 134

104

12 116

56 134

35 NULL

List Head

next next next

The list after the first node is removed:

Address: 116 134

116

56 134

35 NULL

List Head

next next

The function is defined as follows:

void removeFromFront( IntegerNode *head )

{

IntegerNode *discardptr;

if( head == NULL ) // cannot remove node from empty list: stop

{

cerror << endl << “cannot remove node from an empty linked list” << endl;

exit( 1 );

}

discardptr = head;

head = discardptr -> next;

delete discardptr;

}

Algorithm to Remove the Node after a Given Node from a Linked List

The pointer variable discardptr is used to hold the address of the node to be removed from the list.

The pointer variable afterMePtr hold the address of the node that precedes the node to be removed.

The algorithm follows:

Page 7: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 227

1. If the address in the pointer variable afterMePtr is NULL or this node is the last node in the

list (afterMePtr -> next == NULL), then stop.

2. Set the pointer variable discardptr to the address of the node that follows the given node in

the list:

discardptr = afterMePtr -> next;

3. Connect the given node to the node that follows the node to be removed:

afterMePtr -> next = discardptr -> next;

4. Release the node: delete discardptr;

Given the following linked list:

Address: 104 116 134

104

12 116

56 134

35 NULL

List Head

next next next

The list after the second node is deleted: afterMePtr == 104

Address: 104 134

104

12 134

35 NULL

List Head

next next

The function is defined as follows:

void removeAfterMe( IntegerNode * afterMePtr )

{

IntegerNode *discardptr;

if( afterMePtr == NULL || afterMePtr -> next == NULL ) // There is no node to be removed

{

cerror << endl << “there is no node to be removed” << endl;

exit( 1 );

}

discardptr = afterMePtr -> next;

afterMePtr -> next = discardptr -> next;

delete discardptr;

}

Page 8: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 228

Algorithm to Insert a Node at the Front of a Linked List

It is assumed that the data part of the node to be inserted is in the variable dataVal.

The algorithm follows:

1. Create a new node and store its address in the pointer variable newptr:

IntegerNode *newptr = new IntegerNode;

2. Initialize the data part of this new node with the value in dataVal: newptr -> value = dataVal;

3. Connect this node to the previous first node: newptr -> next = head;

4. Make this node the first node: head = newptr;

Given the following linked list:

Address: 104 116 134

104

12 116

56 134

35 NULL

List Head

next next next

And the following node: newptr = 160

Address: 160

40 NULL

next

The list after this node is inserted at the front of the linked list:

Address: 104 116 134

160

12 116

56 134

35 NULL

List Head

next next next

Address: 160

40 104

Next

The function is defined as follows:

Page 9: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 229

void insertAtFront(IntegerNode *head, int dataVal )

{

IntegerNode *newptr = new IntegerNode;

newptr -> value = dataVal;

newptr -> next = head;

head = newptr;

}

Algorithm to Insert a Node after a Given Node in a Linked List

It is assumed that the address of the node that precedes the point of insertion is given and is stored in

the pointer variable afterMePtr.

It is also assumed that the data part of the node to be inserted is in the variable dataVal.

The algorithm follows:

1. If the pointer variable afterMePtr holds NULL, then stop.

2. Create a new node and store its address in the pointer variable newptr:

IntegerNode *newptr = new IntegerNode;

3. Initialize the data part of this new node with the value in dataVal: newptr -> value = dataVal;

4. Connect this node to the node that follows it in the list: newptr -> next = afterMePtr -> next;

5. Connect this node to the node that precedes it in the list: afterMePtr -> next = newptr;

Given the following linked list:

Address: 104 116 134

104

12 116

56 134

35 NULL

List Head

next next next

And the following node: newptr = 160

Address: 160

40 NULL

next

The list after the node is inserted after the second node: AfterMePtr == 116

Page 10: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 230

Address: 104 116 134

104

12 116

56 160

35 NULL

List Head

next next next

Address: 160

40 134

next

The function is defined as follows:

void insertAfterMe(IntegerNode *afterMePtr, int dataVal )

{

if( afterMePtr == NULL ) // Invalid address: stop

{

cerror << endl << “Invalid address” << endl;

exit( 1 );

}

IntegerNode *newptr = new IntegerNode;

newptr -> value = dataVal;

newptr -> next = afterMePtr -> next;

afterMePtr -> next = newptr;

}

Algorithm to Output the Data Parts of the Nodes of a Linked List (List Traversal)

The algorithm follows:

1. Set the current pointer variable currentptr to the address of the first node in the linked list:

currentptr = head;

2. As long as the address in the current pointer variable currentptr is not NULL, do the following:

a. output the data part of the current node : currentptr -> value

b. Set the current pointer variable currentptr to the address of the next node:

currentptr = currentptr -> next;

The function is defined as follows:

Page 11: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 231

void printList((ostream &outs, IntegerNode *head )

{

IntegerNode * currentptr;

currentptr = head;

while( currentptr != NULL )

{

outs << endl << currentptr -> value << endl;

currentptr = currentptr -> next;

}

Algorithm to Destroy a Linked List

The algorithm follows:

1. Set the current pointer variable currentptr to the address in the first node in the linked list:

currentptr = head;

2. As long as the address in pointer variable currentptr is not NULL, do the following:

a. Save the address of the current node (so that it can be released later):

releaseptr = currentptr;

b. Set the current pointer variable currentptr to the address of the next node:

currentptr = currentptr -> next;

c. Release the node: delete releaseptr;

The function is defined as follows:

void destroyList((IntegerNode *head )

{

IntegerNode * currentptr, // to hold the address of the current node

*releaseptr; // to hold the address of the node to be removed

currentptr = head;

while( currentptr != NULL )

{

releaseptr = currentptr;

currentptr = currentptr -> next;

delete releaseptr;

}

Page 12: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 232

Algorithm to Append a Node to a Linked List

It is also assumed that the data part of the node to be inserted is in the variable dataVal.

The algorithm follows:

1. Create a new node and store its address in the pointer variable newptr:

node *newptr = new node;

2. Initialize the data part of this new node with the value in dataVal: newptr -> data = dataVal;

3. Initialize the next part of this node with NULL: newptr -> next = NULL;

4. If the list is empty (head == NULL), do the following:

a. make this node the first node in the list: head = newptr;

5. Otherwise, do the following:

a. Set the current pointer variable currentptr to the address of the first node in the list:

currentptr = head;

b. As long as the next part of the current node is not NULL (currentptr -> next != NULL), do

the following:

i. Set the current pointer variable currentptr to the address of the next node:

currentptr = currentptr -> next;

c. Connect the last node of the list to the new node: currentptr -> next = newptr;

The function is defined as follows:

void appendNode((IntegerNode *head, int dataVal )

{

/*-----------------------create the new node to be inserted -----------------------------------*/

IntegerNode *newptr = new IntegerNode;

newptr -> value = dataVal;

newptr -> next = NULL;

if( head == NULL ) // Make this node the head of the list if the list is empty

head = newptr;

else

{

IntegerNode * currentptr;

currentptr = head;

while( currentptr -> next != NULL ) // find the last node in the list

currentptr = currentptr -> next;

currentptr -> next = newptr; // insert the new node

}

Page 13: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 233

Algorithm for Searching a Linked List

The value to be searched is in the variable target.

The address of the node that contains the value that is being searched is returned if that value is in

the list; otherwise, NULL is returned.

The algorithm follows:

1. Set the current node pointer variable currentPtr to the first node or the address in the pointer

variable head: currentPtr = head;

2. As long as the data in the current node is not the searched value and the address in currentPtr is

not NULL, do the following: ( currentPtr != NULL && currentPtr -> value != target )

a. Make the next node the list the current node: currentPtr = currentPtr -> next;

3. Return the address in the pointer variable currentPtr.

The function is defined as follows:

IntergerNode * searchValue((IntegerNode *head, int target )

{

IntegerNode *currentPtr = head;

while( currentPtr != NULL && currentPtr -> value != target )

currentPtr = currentPtr -> next;

return( currentPtr );

}

Page 14: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 234

Exercise L2

For the following exercises, a node of the linked list is defined as follows:

struct Node

{

int data;

Node * next;

};

A. Pointer variable pt is defined as follows: Node *pt;

Assuming that pt holds the address of a node, write the sequence of statement(s) to store into pointer

variable pt the address of the node that follows this node in the linked list.

B. Given the following linked list (with the address of the first node in the pointer variable head) and

the additional node, do the following:

Address: 128 140 154

128

78 140

23 154

15 NULL

List Head

next next next

Aditional node: newptr = 172

Address: 172

10 NULL

next

1.

a. Show the list after the new node is inserted at the front of the list.

b. Write the sequence of instructions to insert a new node at the front of the list.

2.

a. Show the list after the new node is inserted after the node with address 140.

b. Write the sequence of instructions to insert the node with address in pointer variable

newptr after the node with address in pointer variable predPtr.

3.

a. Show the list after the new node is inserted at the end of (appended) the list.

b. Write the sequence of instruction to append the node with address in pointer variable

newptr at the end of a non-empty list.

4.

a. Show the list after the first node is deleted.

b. Write the sequence of instructions to delete the first node from a non-empty list.

Page 15: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 235

5.

a. Show the list after the node that comes after the node with address 140 is removed from

the list.

b. Write the sequence of instructions to delete from a list the node that comes after the node

with address in pointer variable predPtr.

Exercise L3

An ordered linked list is a linked list such that the data values of the nodes are ordered either in

ascending order or in descending order.

1. Write the definition of the function Node *searchPosition( Node *first, int value) that receives as

arguments the head of an ordered linked list (in ascending order) and a value and does the following:

a. If the list is empty, it returns NULL.

b. If the list is not empty and the value received is less than the data value of the first node in the

list, it returns NULL.

c. Otherwise, it searches the linked list for the node that must precede the node with the value

received in the list and then returns its address.

2. Write the definition of the function void insertNode( Node *first, int value) that receives as

arguments the head of an ordered linked list (in ascending order) and a value and does the following:

a. It first creates a new node and places the value received in the data part of the new node.

b. It then calls function searchPosition( ) to search for the position of this new node in the list.

c. And finally, it inserts the new node in its position in the linked list. Note that the new node is

inserted at the front of the list if NULL is returned by function searchPosition( ).

3. Write the definition of the function int countNode( Node *first) that receives as argument the head of

a linked list and returns the number of nodes in that linked list.

Exercise L4

Write the definition of the function void reverseList( Node * & first ) that receives the head of a non-

empty linked list and reverses its elements: That means the first node becomes the last node in the list

and the last node becomes the first. The function uses the reference parameter to return the address of

the head of the new list.

Page 16: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 236

Stacks

A stack is a list of data designed such that data are retrieved in the reverse of the order in which they

are stored in the list.

You can think of a stack as a hole in the ground: in order to remove an item from the hole, you must

first remove all the items on top of it. For this reason a stack is often called a last in/first out

(LIFO) data structure.

In the following example, data are entered in the stack in the order: A B C D

D

C

B

A

And they are retrieved in the order: D C B A

A stack can be implemented by using an array, a dynamic array, or a linked list.

In the implementation of a stack, a variable (referred to as the top of the stack) is used to hold the

position of the top of the stack: the location of the last data entered in the stack.

The following are the basic operations on a stack:

Operation Description

push Adds an element on top of the stack (if there is room in the stack);

otherwise, indicates that there is no room in the stack.

top Returns the data at the top of the stack.

pop Returns the data at the top of the stack and then removes it from the

top of the stack.

empty Checks if a stack is empty: returns true if it is and false otherwise.

Implementing a Stack with an Array

An array of size CAPACITY is used to hold the elements of a stack.

Elements are entered in the stack at index 0, then 1, then 2, . . ., CAPACITY – 1.

We indicate that a stack is empty by setting its top at position -1 (nothing is entered in the array).

Page 17: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 237

Empty stack: top = -1 top = 2

The class is defined as follows:

[5]

[4]

[3]

[2]

[1]

[0]

[5]

[4]

[3]

[2] 90

[1] 67

[0] 25

Page 18: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 238

/*-------------------------------------------- Stack.h ---------------------------------------------------*/

#ifndef STACK_H

#define STACK_H

const int CAPACITY = 100; // maximum number of elements in the stack

typedef int dataType; // to be set before you compile the program

class Stack

{

public:

Stack( ); // constructor: create an empty stack

void push( dataType dataVal ); // add an element on top of the stack

void pop(dataType & dataVal ); // return the data at the top of the stack and then remove it

void top(dataType & dataVal ); // return the data at the top of the stack

bool isEmpty( ); // return true if the stack is empty and false otherwise

bool isFull( ); // return true if the stack is full and false otherwise

private:

dataType stackArray[ CAPACITY ];

int stackTop; // The top of the stack

};

/*----------------------------------end of Stack.h -----------------------------------------------------------*/

/*----------------------------------------- Stack.cpp --------------------------------------------------------*/

#include <iostream>

#include “Stack.h”

/*------------------------------------ definition of the constructor ----------------------------------------*/

Stack :: Stack( )

{

stackTop = -1; // empty stack

}

/*------------------------------------- member function top( ) ----------------------------------------------*/

/*-----------------use a reference variable to return the data at the top of the stack ------------------*/

void Stack :: top( dataType &dataVal )

{

if( isEmpty( ) ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackArray[ stackTop ];

}

Page 19: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 239

/*---------------------------------- member function pop( ) -------------------------------------------------*/

/*---- Use a reference variable to return the data at the top of the stack and then remove it -------*/

void Stack :: pop( dataType &dataVal )

{

if( isEmpty( ) ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackArray[ stackTop ];

stackTop -- ;

}

/*---------------------------------- member function push( ) ----------------------------------------------*/

void Stack :: push(dataType dataVal )

{

if( isFull( ) ) // the stack is full

{

cerr << endl << “Stack is full: new element cannot be added” << endl;

exit( 1 );

}

/*-----------------------------add the element to the top of the stack ----------------------------------*/

stackTop ++;

stackArray[ stackTop ] = dataVal;

}

/*--------------------------------------- member function isEmpty( )--------------------------------------*/

bool Stack :: isEmpty( )

{

return( stackTop == -1 );

}

/*------------------------------------- member function isFull( ) ---------------------------------------*/

bool Stack :: isFull( )

{

return( stackTop == CAPACITY - 1 );

}

Page 20: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 240

Implementing a Stack with a Dynamic Array

One problem with implementing a stack with an array is that the size of the stack is fixed: one size

fits all. All the stack objects have the same size. With a dynamic array, the size of the array is set by

the constructor.

Elements are entered in the stack in the same way as with static arrays: at index 0, then 1, then 2, . .

., capacity – 1.

We indicate that a stack is empty in the same way that we did with static array: by setting its top at

position -1 (nothing is entered in the array).

The definitions of the member functions push( ), pop( ), top( ), isEmpty( ), and isFull( ) are the

same as their definitions for the implementation of a stack with a static array. However, we must

provide the definitions of the copy constructor, the destructor, and the overloaded assignment

operator for the class.

The class is defined as follows:

/*-------------------------------------------- DStack.h ---------------------------------------------------*/

#ifndef DSTACK_H

#define DTACK_H

typedef int dataType; // to be set before you compile the program

class Stack

{

public:

Stack( int size = 10); // create an empty stack: 10 is the default array size

Stack( const Stack & original ); // copy constructor

~Stack( ); // destructor

const Stack & operator =( const Stack & rightHandSide); // overloaded assignment

void push( dataType dataVal ); // add an element on top of the stack

void pop(dataType & dataVal ); // return the data at the top of the stack and then remove it

void top(dataType & dataVal ); // return the data at the top of the stack

bool isEmpty( ); // return true if the stack is empty and false otherwise

bool isFull( ); // return true if the stack is full and false otherwise

private:

dataType *stackArray; // dynamic array to hold the stack

int capacity; // the size of the array

int stackTop; // the top of the stack

};

/*----------------------------------end of DStack.h -----------------------------------------------------------*/

Page 21: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 241

/*----------------------------------------- DStack.cpp --------------------------------------------------------*/

#include <iostream>

#include “DStack.h”

/*------------------------------------------------------- constructor--------------------------------------------*/

Stack :: Stack( int size ) : capacity ( size )

{

stackArray = new dataType[ size ];

stackTop = -1;

}

/*-------------------------copy constructor Stack( const Stack & original ) -------------------------------*/

/* Initialize the elements of the new stack object with the elements of stack original */

Stack :: Stack( const Stack & original ) : capacity( original.capacity )

{

stackArray = new dataTye [ capacity ];

for ( int i = 0; i < capacity ; i ++ )

stackArray [ i ] = original.stackArray[ i ];

stackTop = original.stackTop;

}

/*-----------------------overloaded assignment operator------------------------------------------------------*/

/* use of const return to avoid left associativity: (A = B) = C */

/* do not copy a list into itself and if the two list do not have the same number of elements, deallocate

the original list and create another one with the same number of elements as the list being copied */

const Stack & Stack :: operator = ( const Stack & rightHandSide )

{

if ( this != & rightHandSide ) // copy only if the two lists are not the same

{

if ( capacity != rightHandSide.capacity )

{

delete [ ] stackArray; // deallocate memory locations for the left side list

capacity = rightHandSide.capacity;

stackArray = new dataType [ capacity ];

}

for ( int i = 0; i < capacity ; i ++ )

stackArray [ i ] = original.stackArray [ i ];

stackTop = rightHandSide.stackTop;

}

return( *this);

}

Page 22: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 242

/*------------------------------------------------destructor ~Stack( )---------------------------------------*/

Stack :: ~Stack( )

{

delete [ ] stackArray;

}

/*---------------------------------- member function push( ) --------------------------------------------*/

void Stack :: push( dataType dataVal )

{

if( isFull( ) ) // the stack is full

{

cerr << endl << “Stack is full: new element cannot be added” << endl;

exit( 1 );

}

/*-----------------------------add the element at the top of the stack -------------------------------*/

stackTop ++;

stackArray[ stackTop ] = dataVal;

}

/*----------------------------------member function top( )------------------------------------------------*/

/*-----------------use a reference variable to return the data at the top of the stack ----------------*/

void Stack :: top( dataType &dataVal )

{

if( isEmpty( ) ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackArray[ stackTop ];

}

/*----------------------------- member function isEmpty( ) ----------------------------------------------*/

bool Stack :: isEmpty( )

{

return( stackTop == -1 );

}

Page 23: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 243

/*----------------------------------member function isFull( ) ----------- ------------------------------------*/

bool Stack :: isFull( )

{

return( stackTop == capacity - 1 );

}

/*---------------------------------- member function pop( ) -----------------------------------------------*/

/*---- Use a reference variable to return the data at the top of the stack and then remove it -----*/

void Stack :: pop( dataType &dataVal )

{

if( isEmpty( ) ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackArray[ stackTop ];

stackTop -- ;

}

/*---------------------------------------------end of DStack.cpp-----------------------------------------------*/

Exercise L5

1.

Suppose that the following operations are performed

on an empty stack s:

s.push( 5);

s.push(2);

s.push(10);

s.push(3);

Show the array and the value of variable stackTop

after the execution of these operations.

stackTop = -1

[4]

[3]

[2]

[1]

[0]

2.

Page 24: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 244

Suppose that the following operations are performed on

an empty stack s:

s.push( 5);

s.push(2);

s.pop(num);

s.push(10);

s.top(num);

s.push(3);

Show the array and the values of the variables num1, num2,

and stackTop after the execution of these operations.

stackTop = -1

[4]

[3]

[2]

[1]

[0]

3. Write the sequence of statements to create an empty stack of 10 elements using a dynamic array.

4. Write the sequence of statements to perform the push operation on a stack implemented as an array

that is not full. What is the condition for a stack implemented as an array to be full?

5. Write the sequence of statements to perform the pop and the top operations on a stack implemented

as an array that is not empty. What is the condition for a stack implemented as an array to be empty?

6. Write the sequence of instructions to read 10 integer values and to use a stack to print them in the

reverse of the order that they have been read in.

Implementing a Stack with a Linked List

An array-based implementation of a stack imposes an upper limit on the size of the stack. That

means that a stack can become full and the user of this stack must be aware of this fact.

A linked list implementation of a stack solves this problem by allowing a stack to grow without limit

and to shrink without wasting unused storage.

With the linked list implementation, the top of the stack is implemented by the head of the list, and

a stack is empty when the head of the list holds NULL.

/*-------------------------------------------- LStack.h ---------------------------------------------------*/

#ifndef LSTACK_H

#define LSTACK_H

typedef int dataType; // to be set before you compile the program

/*------------------------------ Definition of the linked list node ------------------------------------*/

struct StackNode

{

dataType data;

StackNode * next;

};

Page 25: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 245

class Stack

{

public:

Stack( ); // create an empty stack

Stack( const Stack & original ); // copy constructor

~Stack( ); // destructor

const Stack & operator =( const Stack & rightHandSide); // overloaded assignment

void push( dataType dataVal ); // add an element on top of the stack

void pop(dataType & dataVal ); // return the data at the top of the stack and then remove it

void top(dataType & dataVal ); // return the data at the top of the stack

bool isEmpty( ); // return true if the stack is empty and false otherwise

private:

stackNode *stackTop; // head of the linked list refers to the top of the stack

};

/*----------------------------------end of LStack.h -----------------------------------------------------------*/

/*----------------------------------------- LStack.cpp --------------------------------------------------------*/

#include <iostream>

#include “LStack.h”

/*------------------------------------------------------- constructor-------------------------------------------*/

Stack :: Stack( ) : stackTop( NULL )

{

}

/*--------------------------------destructor ~Stack( )--------------------------------------------------------*/

Stack :: ~Stack( )

{

StackNode *releasePtr; // to hold the address of the node to be removed

while( StackTop != NULL )

{

releasePtr = StackTop;

StackTop = StackTop -> next;

delete releasePtr;

}

}

Page 26: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 246

/*-------------------------copy constructor Stack( const Stack & original ) ------------------------------*/

/* Create a new stack object and initialize its elements with the elements of the original stack */

Stack :: Stack( const Stack & original )

{

if( original.stackTop == NULL ) // original stack is empty

stackTop = NULL;

else

{

StackNode *from, // hold the address of the current node in the original stack

*to; // hold the address of the new node of the new stack

/* - create the first node of the new stack and copy the first node of the original stack to it -*/

to = new StackNode;

to -> data = original. stackTop -> data;

stackTop = to; // copy the first node

/*----------------------------------- copy the rest of the nodes -------------------------------------------*/

from = original.stackTop -> next;

while( from != NULL )

{

to -> next = new StackNode; // create a new node and connect it to the current node

to = to -> next; // make the new node the current node

to -> data = from -> data // copy the data to the current node

from = from -> next; // make the next node in the original stack the current node

}

to -> next = NULL;

}

}

/*-----------------------overloaded assignment operator---------------------------------------------------------*/

/* use of const return to avoid left associativity: (A = B) = C */

/* do not copy a stack into itself. First destroy the left hand side stack and create another one with the

same number of nodes as the right hand side stack */

const Stack & Stack :: operator = ( const Stack & rightHandSide )

{

if ( this != & rightHandSide ) // copy only if the two stacks are not the same

{

this -> ~Stack( ); // destroy the left hand side stack

if ( rightHandSide.empty( ) ) // the right hand side stack is empty

stackTop = NULL;

else

Page 27: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 247

{

StackNode *from, // hold the address of the current node in the right hand side stack

*to; // hold the address of the new node of the left hand side stack

/* create the first node of the left hand side stack and copy the first node of the right hand

side stack to it */

to = new StackNode;

to -> data = rightHandSide. stackTop -> data;

stackTop = to; // copy the first node

/*----------------------------------- copy the rest of the nodes -------------------------------------*/

from = rightHandSide.stackTop -> next;

while( from != NULL )

{

to -> next = new StackNode; // create a new node and connect it to the current node

to = to -> next; // make the new node the current node

to -> data = from -> data // copy the data to the current node

from = from -> next;// make the next node in the right hand side stack the current node

}

to -> next = NULL;

}

}

return( *this );

}

/*---------------------------------- member function push( ) -----------------------------------------------*/

void Stack :: push( dataType dataVal )

{

/*-----------------------------add the element to the top of the stack ----------------------------------*/

StackNode *newptr = new StackNode;

newptr -> data = dataVal;

newptr -> next = stackTop;

stackTop = newptr;

}

/*------------------------------- member function isEmpty( ) ----------------------------------------*/

bool Stack :: isEmpty( )

{

return( stackTop == NULL );

}

Page 28: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 248

/*---------------------------------- member function top( ) --------------------------------------------------*/

/*--------------------------------return the data at the top of the stack -------------------------------------*/

void Stack :: top(dataType & dataVal )

{

if( stackTop == NULL ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackTop -> data;

}

/*---------------------------------- member function pop -----------------------------------------------------*/

/*---------------return the data at the top of the stack and clear the top of the stack -----------------*/

void Stack :: pop(dataType & dataVal );

{

if( stackTop == NULL ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackTop -> data; // return the data at the top of the stack

StackNode *discardptr; // to hold the address of the node to be removed

discardptr = stackTop;

stackTop = stackTop -> next; // set the top of the stack to the next node

delete discardptr;

}

/*---------------------------------------------end of LStack.cpp-------------------------------------------*/

Exercise L6

For the following exercises, assume that the structure used to define a node of a linked list is named

StackNode (with the data members data and next) and the head of the list (top of the stack) has its

address in pointer variable stackTop.

1. Write the sequence of statements to create an empty stack using a linked list.

2. Write the sequence of statements to perform the push operation on a stack (implemented as a linked

list) using the value in the variable dataVAl.

3. Write the sequence of statements to perform the pop and the top operations on a stack implemented

as a linked list that is not empty. The value retrieved front the stack will be stored in the variable

dataVal.

4. What is the condition for a stack implemented as a linked list to be empty?

Page 29: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 249

Queues

A queue is a list of data designed such that data are retrieved in the order in which they are stored in

the list.

You can think of a queue as a line in front of a cash register: the first person that arrives at the cash

register is the first to be served. For this reason a queue is often called a first in/first out (FIFO)

data structure.

In the following example, data are entered in the queue in the order: A B C D

D

C

B

A

And they are retrieved in the order: A B C D

A queue can be implemented with an array, a dynamic array, or a linked list.

In the implementation of a queue, a variable (referred to as the front/head of the queue) is used to

hold the position of the first element of the queue and a variable (referred to as the back/tail/rear of

the queue) is used to hold the position where the new element will be added in the queue.

The following are the basic operations on a queue:

Operation Description

enqueue Adds an element to the back of the queue: Indicate if there is no

room in the queue for the new element.

front Returns the data at the front of the queue.

dequeue Returns the data at the front of the queue and then removes it from

the front of the queue.

empty Checks if a queue is empty: returns true if it is and false otherwise.

Implementing a Queue with a Circular Array

An array of size CAPACITY is used to hold the elements of a queue.

Elements are entered and retrieved from the queue in the order, index 0, then 1, then 2, . . ., then

CAPACITY – 1, then 0, then 1 . . . etc.

Page 30: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 250

A variable numElement is used to hold the number of elements entered in the queue:

0 <= numElement <= CAPACITY

A queue is empty if numElement = 0.

A queue is full if numElement = CAPACITY.

Empty queue: front = 0 front = 1

back = 0 back = 4

numElement = 0 numElement = 3

The class is defined as follows:

/*-------------------------------------------- Queue.h ---------------------------------------------------*/

#ifndef QUEUE_H

#define QUEUE_H

const int CAPACITY = 100; // maximum number of elements in the queue

typedef int dataType; // to be set before you compile the program

class Queue

{

public:

Queue( ); // constructor: create an empty queue

void enqueue( dataType dataVal ); // add an element to the back of the queue

void dequeue(dataType & dataVal ); // return the data at the front of the queue and remove it

void front(dataType & dataVal ); // return the data at the front of the queue

bool isEmpty( ); // return true if the queue is empty and false otherwise

bool isFull( ); // return true if the queue is full and false otherwise

private:

dataType queueArray[ CAPACITY ];

int queueFront; // the front of the queue

int queueBack; // the back of the queue

int numElement; // the number of elements in the queue

};

/*----------------------------------end of Queue.h -----------------------------------------------------------*/

[4]

[3]

[2]

[1]

[0]

[4]

[3] 25

[2] 90

[1] 67

[0]

Page 31: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 251

/*----------------------------------------- Queue.cpp --------------------------------------------------------*/

#include <iostream>

#include “Queue.h”

/*------------------------------------ definition of the constructor ----------------------------------------*/

Queue:: Queue( ) // empty queue

{

QueueFront = 0;

QueueBack = 0;

NumElement = 0;

}

/*----------------------------------definition of member function enqueue( )------------------------*/

void Queue :: enqueue( dataType dataVal )

{

if( isFull( ) ) // the queue is full

{

cerr << endl << “Queue is full: new element cannot be added” << endl;

exit( 1 );

}

/*-----------------------------add the element to the back of the queue---------------------------*/

queueArray[ queueBack ] = dataVal;

queueBack ++;

if( queueBack == CAPACITY )

queueBack = 0; // queueBack = ( queueBack +1) % CAPACITY

numElement++;

}

/*----------------------------------definition of member function front( ) -----------------------------*/

/*-----------------use a reference variable to return the data at the front of the queue------------*/

void Queue :: front( dataType &dataVal )

{

if( isEmpty( ) ) // the queueis empty

{

cerr << endl << “Queue is empty” << endl;

exit( 1 );

}

dataVal = queueArray[ queueFront ];

}

Page 32: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 252

/*-------------------------definition of member function dequeue-- ------------------------------------*/

/*---- Use a reference variable to return the data at the front of the queue and then remove it -*/

void Queue :: dequeue( dataType &dataVal )

{

if( isEmpty( ) ) // the queue is empty

{

cerr << endl << “Queue is empty” << endl;

exit( 1 );

}

dataVal = stackArray[ queueFront ];

queueFront ++ ;

if( queueFront == CAPACITY )

queueFront = 0; // queueFront = (queueFront + 1) % CAPACITY

numElement--;

}

/*---------------------------------------------- member function isEmpty-------------------------------------*/

bool Queue:: isEmpty( )

{

return( numElement == 0 );

}

/*---------------------------------------------- member function isFull ---------------------------------------*/

bool Queue :: isFull( )

{

return( numElement == CAPACITY );

}

Implementing a Queue with a Circular Dynamic Array

One problem with implementing a queue with an array is that the size of the queue is fixed: one size

fits all. All the queue objects have the same size. With a dynamic array, the size of the array is set

by the constructor.

Elements are entered and retrieved from the queue in the same way as with static arrays: at index 0,

then 1, then 2, . . ., capacity – 1, then 0, then 1 . . .

As with static arrays, a variable named numElement is used to hold the number of elements

entered in the queue:

0 <= numElement <= capacity

Page 33: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 253

A queue is empty if numElement = 0.

A queue is full if numElement = capacity.

The definitions of the member functions enqueue( ), front( ), dequeue( ), isEmpty( ), and isFull( )

are the same as their definitions for the implementation of a queue with a static array. However, we

must provide the definitions of the copy constructor, the destructor, and the overloaded assignment

operator for the class.

The definitions of the copy constructor, the destructor, and the overloaded assignment operator are

similar to those provided for the implementation of a stack with dynamic arrays.

The class is defined as follows:

/*-------------------------------------------- DQueue.h ---------------------------------------------------*/

#ifndef DQUEUE_H

#define DQUEUE_H

typedef int dataType; // to be set before you compile the program

class Queue

{

public:

Queue( int size = 10); // create an empty queue: 10 is the default array size

Queue( const Queue & original ); // copy constructor

~Queue( ); // destructor

const Queue & operator =( const Queue & rightHandSide); // overloaded assignment

void enqueue( dataType dataVal ); // add an element to the back of the queue

void dequeue(dataType & dataVal ); // return the data at the front of the queue and remove it

void front(dataType & dataVal ); // return the data at the front of the queue

bool isEmpty( ); // return true if the queue is empty and false otherwise

bool isFull( ); // return true if the queue is full and false otherwise

private:

dataType *queueArray; // dynamic array to hold the queue

int capacity; // the size of the array

int queueFront; // the position of the front of the queue

int queueBack; // the position of the back of the queue

int numElement; // the number of element in the queue

};

/*-----------------------------------------end of DQueue.h --------------------------------------------------*/

Page 34: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 254

/*----------------------------------------- DQueue.cpp ------------------------------------------------------*/

#include <iostream>

#include “DQueue.h”

/*------------------------------------ definition of the constructor ----------------------------------------*/

Queue:: Queue( int size ) : capacity( size )

{

queueArray = new dataType[ size ];

QueueFront = 0;

QueueBack = 0;

NumElement = 0;

}

<Definitions of the other member functions>

/*-------------------------------- end of DQueue.cpp ---------------------------------------------------------*/

Exercise L7

Write the definitions of the copy constructor, the destructor, and the overloaded assignment operator of

the class Queue implemented with a dynamic circular array.

Exercise L8

1.

Suppose that the following operations are performed

on an empty queue q:

q.enqueue( 5);

q.enqueue(2);

q.enqueue( 9);

q.dequeue( num1);

q.enqueue(3);

q.front(num2);

q.enqueue(10);

q.dequeue(num3);

q.enqueue( 7);

q.enqueue(4);

q.dequeue( num4 );

Show he circular array, and the values of the variables

QueueFront, QueueBack, NumElement, num1, num2,

num3, and num4 after the execution of these operations.

QueueFront = 0

QueueBack = 0

NumElement = 0

[4]

[3]

[2]

[1]

[0]

Page 35: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 255

2.

Suppose that the following operations are performed on

the queue q shown on the right:

q.enqueue( 5);

q.enqueue(2);

q.enqueue( 9);

q.dequeue( num1);

q.dequeue(num2);

q.front(num3);

q.dequeue( num4);

q.dequeue(num5);

q.enqueue( 7);

q.dequeue( num6);

Show he circular array, and the values of the variables

QueueFront, QueueBack, NumElement, num1, num2, num3,

num4, num5, and num6 after the execution of these operations

QueueFront = 2

QueueBack = 4

NumElement = 2

[4]

[3] 15

[2] 20

[1]

[0]

3. Write the sequence of statements to enter (enqueue) the value in variable dataVal into a queue

(implemented with a circular array) that is not full.

4. Write the sequence of statements to remove (dequeue) one element from a queue (implemented with

a circular array) that is not empty and to store its value into the variable dataVal.

5. Write the definition of a member function dataType getlast( ) that returns the value of the last

element entered in the queue.

6. Write the definition of a member function void printQueue1( ) that outputs the values of the

elements of a queue (implemented with a circular array) in the order in which they are entered in the

queue (with a possible destruction of the queue).

7. Write the definition of a member function void printQueue2( ) that outputs the values of the

elements of a queue (implemented with a circular array) in the order in which they are entered in the

queue (without destroying the queue).

Exercise L9

The service time of an individual that arrives at a cash register is the time it will take the cashier to

service that individual and the turn-around time of that individual is the sum of his service time and his

waiting time (that means the time that he must wait to get the service). Ten individuals have arrived at

the same time at the cash register and their service times are input in their order of arrival.

1. Write a code segment to define a queue that can hold at least 10 integer values, and to read these

service times into that queue.

2. Assuming that there is no interruption of service between an individual and the next one in the

queue, write a code segment to compute each individual’s turn-around time, and the average turn-

around time.

Page 36: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 256

Implementing a Queue with a Linked List

An array-based implementation of a queue imposes an upper limit on the size of the queue. That

means that a queue can become full and the user of this queue must be aware of this fact.

A linked list implementation of a queue solves this problem by allowing a queue to grow without

limit and to shrink without wasting unused storage.

With the linked list implementation, the head/front of the queue is implemented by the head of the

list, and a new pointer variable is defined to hold the address of the back/tail of a queue.

A queue is empty when the head of the list holds NULL.

/*-------------------------------------------- LQueue.h ---------------------------------------------------*/

#ifndef LQUEUE_H

#define LQUEUE_H

typedef int dataType; // to be set before you compile the program

/*------------------------------ Definition of the linked list node ------------------------------------*/

struct QueueNode

{

dataType data;

QueueNode * next;

};

class Queue

{

public:

Queue( ); // create an empty stack

Queue ( const Queue & original ); // copy constructor

~ Queue ( ); // destructor

const Queue & operator =( const Queue & rightHandSide); // overloaded assignment

void enqueue( dataType dataVal ); // add an element at the back of the queue

void dequeue(dataType & dataVal ); // return the data at the front of the queue and remove it

void front(dataType & dataVal ); // return the data at the front of the queue

bool isEmpty( ); // return true if the queue is empty and false otherwise

private:

queueNode *queueFront; // head of the linked list refers to the front of the queue

queueNode *queueBack; // the last node entered in the queue

};

/*----------------------------------end of LQueue.h -----------------------------------------------------------*/

Page 37: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 257

/*----------------------------------------- LQueue.cpp --------------------------------------------------------*/

#include <iostream>

#include “L Queue.h”

/*------------------------------------------------------- constructor-------------------------------------------*/

Queue :: Queue ( ) : queueFront( NULL ), queueBack( NULL )

{

}

/*--------------------------------destructor ~ Queue ( )----------------------------------------------------*/

Queue :: ~ Queue ( )

{

QueueNode *releasePtr; // to hold the address of the node to be removed

while( queueFront != NULL )

{

releasePtr = queueFront;

queueFront = queueFont -> next;

delete releasePtr;

}

}

/*-------------------------copy constructor Queue( const Queue & original ) ------------------------------*/

/* Create a new queue object and initialize its elements with the elements of the original Queue */

Queue :: Queue ( const Queue & original )

{

if( original.queueFront == NULL ) // original queue is empty

queueFront = queueBack = NULL;

else

{

QueueNode *from, // hold the address of the current node in the original queue

/* - create the first node of the new queue and copy the first node of the original queue to it -*/

queueFront = queueBack = new QueueNode;

queueFront -> data = original. queueFront -> data;

/*----------------------------------- copy the rest of the nodes -------------------------------------------*/

from = original.queueFront -> next;

while( from != NULL )

{

queueBack -> next = new QueueNode;

// create a new node and connect it to the current last node

Page 38: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 258

queueBack = queueBack -> next; // make the new node the current last node

queueBack -> data = from -> data // copy the data to the current last node

from = from -> next; // make the next node in the original queue the current node

}

queueBack -> next = NULL;

}

}

/*-----------------------overloaded assignment operator---------------------------------------------------------*/

/* use of const return to avoid left associativity: (A = B) = C */

/* do not copy a queue into itself. First destroy the left hand side queue and create another one with the

same number of nodes as the right hand side queue */

const Queue & Queue :: operator = ( const Queue & rightHandSide )

{

if ( this != & rightHandSide ) // copy only if the two queues are not the same

{

this -> ~ Queue ( ); // destroy the left hand side queue

if ( rightHandSide.empty( ) ) // the right hand side queue is empty

queueFront = queueBack = NULL;

else

{

QueueNode *from, // hold the address of the current node in the original queue

/* create the first node of the new queue and copy the first node of the original queue to it*/

queueFront = queueBack = new QueueNode;

queueFront -> data = rightHandSide. queueFront -> data;

/*-------------------------------- copy the rest of the nodes --------------------------------------*/

from = rightHandSide.queueFront -> next;

while( from != NULL )

{

queueBack -> next = new QueueNode;

// create a new node and connect it to the current last node

queueBack = queueBack -> next; // make the new node the current last node

queueBack -> data = from -> data // copy the data to the current last node

from = from -> next; // make the next node in the original queue the current node

}

queueBack -> next = NULL;

}

}

return( *this );

}

Page 39: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 259

/*---------------------------------- member function enqueue( ) -----------------------------------------------*/

void Queue :: enqueue( dataType dataVal )

{

/*--------------------------------add the element to the back of the queue ----------------------------------*/

QueueNode *newptr = new QueueNode;

newptr -> data = dataVal;

newptr -> next = NULL;

if( queueFront != NULL) // the queue is not empty

{

queueBack -> next = newptr; // connect the last node to the new node

queueBack = newptr; // make the new node the last node

}

else

queueFront = queueBack = newptr;

}

/*---------------------------------- member function front( ) --------------------------------------------------*/

/*--------------------------------return the data at the front of the queue -------------------------------------*/

void Queue :: front(dataType & dataVal )

{

if( queueFront == NULL ) // the queue is empty

{

cerr << endl << “Queue is empty” << endl;

exit( 1 );

}

dataVal = queueFront -> data;

}

/*---------------------------------- member function dequeue( )-----------------------------------------------*/

/*---------------return the data at the front of the queue and clear the front of the queue -----------------*/

void Queue :: dequeue(dataType & dataVal );

{

if( queueFront == NULL ) // the queue is empty

{

cerr << endl << “Queue is empty” << endl;

exit( 1 );

}

dataVal = queueFront -> data; // return the data at the front of the queue

QueueNode *discardptr; // to hold the address of the node to be removed

discardptr = queueFront;

queueFront = queueFront -> next; // set the front of the queue to the next node

delete discardptr;

Page 40: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 260

if(queueFront == NULL )

queueBack = NULL;

}

/*------------------------------- member function isEmpty( ) ----------------------------------------*/

bool Queue :: isEmpty( )

{

return( queueFront == NULL );

}

/*---------------------------------------------end of LQueue.cpp-------------------------------------------*/

Exercise L10

For the following exercises, assume that the structure used to define a node of a linked list is named

QueueNode (with the data members data and next) and the head of the list (front of the queue) has its

address in pointer variable queueFront, and the tail of the queue has its address in the pointer variable

queueBack.

1. Write the sequence of statements to create an empty queue using a linked list.

2. Write the sequence of statements to perform the enqueue operation (with the value in variable

dataVal) on a queue (implemented with a linked list).

3. Write the sequence of statements to perform the dequeue operation on a queue (implemented with a

linked list) that is not empty and to store the value into the variable dataVal.

4. Write the definition of a member function dataType getlast( ) (of the class Queue implemented

with a linked list) that returns the value of the last element entered in the queue.

5. Write the definition of a member function void printQueue2( ) (of the class Queue implemented

with a linked list) that outputs the values of the elements of a queue in the order in which they are

entered in the queue (without destroying the queue).

Page 41: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 261

Class Templates

In addition to function templates, you can define a class that can be applied to more than one data

type.

A class that can be applied to more than one data type is referred to as a class template.

You define a class template in the same way that you define a function template by preceding its

definition with the keyword template followed by a template parameter specified in angle brackets

as follows:

template < class T > or

template < typename T >

Where: T is the type parameter that represents the different data types that can be used in the

definition of the class.

Member functions of a class template are defined as function templates.

In the function prototypes and the definitions of the member functions and friend functions of a class

template, you follow the name of the class with < T >. Example: Stack< T >.

Example

The following is the class template that corresponds to the class Stack implemented with a static array:

/*-------------------------------------------- Stack.Th ---------------------------------------------------*/

#ifndef STACK_TH

#define STACK_TH

#include <iostream>

using namespace std;

const int CAPACITY = 100; // maximum number of elements in the stack

template < class dataType >

class Stack

{

public:

Stack( ); // constructor: create an empty stack

void push( dataType dataVal ); // add an element on top of the stack

void pop(dataType & dataVal ); // return the data at the top of the stack and then remove it

void top(dataType & dataVal ); // return the data at the top of the stack

bool isEmpty( ); // return true if the stack is empty and false otherwise

bool isFull( ); // return true if the stack is full and false otherwise

private:

dataType stackArray[ CAPACITY ];

int stackTop; // The top of the stack

};

Page 42: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 262

/*------------------------------------ definition of the constructor ----------------------------------------*/

template < class dataType >

Stack<dataType> :: Stack( )

{

stackTop = -1; // empty stack

}

/*------------------------------------- member function top( ) ----------------------------------------------*/

/*-----------------use a reference variable to return the data at the top of the stack ------------------*/

template < class dataType >

void Stack<dataType> :: top( dataType &dataVal )

{

if( isEmpty( ) ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackArray[ stackTop ];

}

/*---------------------------------- member function pop( ) -------------------------------------------------*/

/*---- Use a reference variable to return the data at the top of the stack and then remove it -------*/

template < class dataType >

void Stack<dataType> :: pop( dataType &dataVal )

{

if( isEmpty( ) ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackArray[ stackTop ];

stackTop -- ;

}

Page 43: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 263

/*---------------------------------- member function push( ) ----------------------------------------------*/

template < class dataType >

void Stack<dataType>:: push(dataType dataVal )

{

if( isFull( ) ) // the stack is full

{

cerr << endl << “Stack is full: new element cannot be added” << endl;

exit( 1 );

}

/*-----------------------------add the element to the top of the stack ----------------------------------*/

stackTop ++;

stackArray[ stackTop ] = dataVal;

}

/*--------------------------------------- member function isEmpty( )--------------------------------------*/

template < class dataType >

bool Stack<dataType> :: isEmpty( )

{

return( stackTop == -1 );

}

/*------------------------------------- member function isFull( ) ---------------------------------------*/

template < class dataType >

bool Stack<dataType> :: isFull( )

{

return( stackTop == CAPACITY - 1 );

}

#endif

/*------------------------------------------------end of file Stack.Th---------------------------------------------*/

Using a Class Template to Define Objects

You use a class template to define an object by specifying the data type to be used for the parameter

type.

Examples

Stack<int> stackOfIntegers;

Stack<char> stackOfCharacters, stch;

Stack<Employee> stackOfEmployees;

Page 44: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 264

Exercise L11

1. Write the class template that corresponds to the class Stack implemented with a Dynamic array.

2. Write the class template that corresponds to the class Queue implemented with a Dynamic array.

Class Template Implemented with a Linked List

One way to define a class template implemented with a linked list is to write the structure (or the

class) definition of the linked list node in a private/public section of the class template definition.

Example

The following is the class template that corresponds to the class Stack implemented with a linked list:

/*-------------------------------------------- LStack.Th ---------------------------------------------------*/

#ifndef LSTACK_TH

#define LSTACK_TH

#include <iostream>

using namespace std;

template < class dataType >

class Stack

{

public:

Stack( ); // create an empty stack

Stack( const Stack<dataType> & original ); // copy constructor

~Stack( ); // destructor

const Stack & operator =( const Stack<dataType> & rightHandSide);

void push( dataType dataVal ); // add an element on top of the stack

void pop(dataType & dataVal ); // return the data at the top of the stack and then remove it

void top(dataType & dataVal ); // return the data at the top of the stack

bool isEmpty( ); // return true if the stack is empty and false otherwise

private:

/*----------------- Definition of the linked list node --------------------------------*/

struct StackNode

{

dataType data;

StackNode * next;

};

stackNode *stackTop; // head of the linked list refers to the top of the stack

};

Page 45: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 265

/*------------------------------------------------------- constructor-------------------------------------------*/

template < class dataType >

Stack<dataType> :: Stack( ) : stackTop( NULL )

{

}

/*--------------------------------destructor ~Stack( )--------------------------------------------------------*/

template < class dataType >

Stack<dataType> :: ~Stack( )

{

StackNode *releasePtr; // to hold the address of the node to be removed

while( StackTop != NULL )

{

releasePtr = StackTop;

StackTop = StackTop -> next;

delete releasePtr;

}

}

/*-------------------------copy constructor Stack( const Stack & original ) ------------------------------*/

/* Create a new stack object and initialize its elements with the elements of the original stack */

template < class dataType >

Stack<dataType> :: Stack( const Stack<dataType> & original )

{

if( original.stackTop == NULL ) // original stack is empty

stackTop = NULL;

else

{

StackNode *from, // hold the address of the current node in the original stack

*to; // hold the address of the new node of the new stack

/* - create the first node of the new stack and copy the first node of the original stack to it -*/

to = new StackNode;

to -> data = original. stackTop -> data;

stackTop = to; // copy the first node

/*----------------------------------- copy the rest of the nodes -------------------------------------------*/

from = original.stackTop -> next;

while( from != NULL )

{

to -> next = new StackNode; // create a new node and connect it to the current node

to = to -> next; // make the new node the current node

to -> data = from -> data // copy the data to the current node

Page 46: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 266

from = from -> next; // make the next node in the original stack the current node

}

to -> next = NULL;

}

}

/*-----------------------overloaded assignment operator---------------------------------------------------------*/

/* use of const return to avoid left associativity: (A = B) = C */

/* do not copy a stack into itself. First destroy the left hand side stack and create another one with the

same number of nodes as the right hand side stack */

template < class dataType >

const Stack<dataType> & Stack<dataType> ::operator = (const Stack<dataType> &rightHandSide)

{

if ( this != & rightHandSide ) // copy only if the two stacks are not the same

{

this -> ~Stack( ); // destroy the left hand side stack

if ( rightHandSide.empty( ) ) // the right hand side stack is empty

stackTop = NULL;

else

{

StackNode *from, // hold the address of the current node in the right hand side stack

*to; // hold the address of the new node of the left hand side stack

/* create the first node of the left hand side stack and copy the first node of the right hand

side stack to it */

to = new StackNode;

to -> data = rightHandSide. stackTop -> data;

stackTop = to; // copy the first node

/*----------------------------------- copy the rest of the nodes -------------------------------------*/

from = rightHandSide.stackTop -> next;

while( from != NULL )

{

to -> next = new StackNode; // create a new node and connect it to the current node

to = to -> next; // make the new node the current node

to -> data = from -> data // copy the data to the current node

from = from -> next;// make the next node in the right hand side stack the current node

}

to -> next = NULL;

}

}

return( *this );

}

Page 47: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 267

/*---------------------------------- member function push( ) -----------------------------------------------*/

template < class dataType >

void Stack<dataType>:: push( dataType dataVal )

{

/*-----------------------------add the element to the top of the stack ----------------------------------*/

StackNode *newptr = new StackNode;

newptr -> data = dataVal;

newptr -> next = stackTop;

stackTop = newptr;

}

/*------------------------------- member function isEmpty( ) ----------------------------------------*/

template < class dataType >

bool Stack<dataType> :: isEmpty( )

{

return( stackTop == NULL );

}

/*---------------------------------- member function top( ) --------------------------------------------------*/

/*--------------------------------return the data at the top of the stack -------------------------------------*/

template < class dataType >

void Stack<dataType> :: top(dataType & dataVal )

{

if( stackTop == NULL ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackTop -> data;

}

/*---------------------------------- member function pop -----------------------------------------------------*/

/*---------------return the data at the top of the stack and clear the top of the stack -----------------*/

template < class dataType >

void Stack<dataType> :: pop(dataType & dataVal );

{

if( stackTop == NULL ) // the stack is empty

{

cerr << endl << “Stack is empty” << endl;

exit( 1 );

}

dataVal = stackTop -> data; // return the data at the top of the stack

StackNode *discardptr; // to hold the address of the node to be removed

discardptr = stackTop;

stackTop = stackTop -> next; // set the top of the stack to the next node

Page 48: Linked Lists, Stacks, and Queues · ©2011 Gilbert Ndjatou Page 221 Linked Lists, Stacks, and Queues Linked Lists A linked list is a series of connected nodes allocated in the heap.

©2011 Gilbert Ndjatou Page 268

delete discardptr;

}

#endif

/*---------------------------------------------end of LStack.Th-------------------------------------------*/

Exercise L12

Write the class template of the class Queue implemented with a linked list.