Sie sind auf Seite 1von 67

12304

DATA STRUCTURES AND ALGORITHMS UNIT I


DYNAMIC MEMORY ALLOCATION

Dynamic memory allocation: When an array is defined, a specified amount of memory is set aside at compile time, which may not be utilized fully or may not be sufficient. If a situation arises in which the amount of memory required is unknown at compile time, the memory allocation can be performed during execution. Such a technique of allocating memory during runtime on demand is known as dynamic memory allocation. C ++ provides two special operators to perform memory management dynamically. They are: new operator for dynamic memory allocation delete operator for dynamic memory deallocation

new Operator
The new operator is used to allocate memory locations for holding the specified data type, dynamically on demand. The general syntax of new operator is PtrVar = new DataType [size in integer]; The PtrVar is a pointer. The operator new allocates a specified amount of memory during runtime and returns a pointer to that memory location. The new operator returns NULL if the memory is not allocation is unsuccessful. Example: int *a; a = new int[100]; In this example an integer pointer is created. In the second statement, memory for 100 integers is allocated using the new operator. This new operator returns a pointer to this memory location and the pointer is stored in a. In this way memory can be allocated for any type of data type. The dynamic memory allocation for structures is done as shown. struct date { int day; int month; int year; }; date *dp; dp = new date; 1.1

In the above example, a structure called date is defined and a pointer of type date structure is created with name dp. Now, the new operator is used to allocate memory for one record of this structure. Since we are not creating an array of structures here, the subscript is not used with the data type.

delete operator
The new operators counterpart, delete ensures the safe and efficient use of memory. This operator is used to return the memory allocated by the new operator back to the memory pool. Memory thus released, will be reused by other parts of the program. The general syntax of delete operator is delete PtrVar; where PtrVar holds the pointer returned by the memory allocation function new operator. The memory allocated using the new operator should be released by the delete operator. Example: delete a; The delete operator in the above example releases the memory locations pointed by a and adds the released memory to the memory pool.

EXCEPTION HANDLING
When sophisticated software is developed, two main techniques for building reliable software such as fault avoidance and fault tolerance are adopted. Fault tolerance deals with the prevention of fault occurrence by eliminating the possible flaws during the development phase itself. Fault tolerance deals with the method of providing services for handling the errors during the execution of the application. In C ++, exception handling allows to build fault tolerant systems. Exception refers to unexpected condition in a program. The unusual conditions could be faults, causing an error which in turn causes the program to fail. The error handling mechanism of C++ is generally referred to as exception handling. It provides a straight forward mechanism for adding reliable error handling mechanism in a program. Exceptions are classified into two types. They are, Synchronous exceptions Asynchronous exceptions

The exceptions which occur during the program execution, due to some fault in the input-data are known as synchronous exceptions. For instance, errors such as out-ofrange, overflow, and so on belong to the class of synchronous exceptions. The exceptions caused by events or faults unrelated to the program and beyond control of program are called asynchronous exceptions. For instance, errors such as keyboard 1.2

interrupts, hardware malfunctions, disk failure, and so on belong to the class of asynchronous exceptions. C ++ handles synchronous exceptions only. When a program encounters an abnormal situation for which it is not designed, the user may transfer control to some other part of the program that is designed to deal with the problem. This is done throwing an exception. The exception handling mechanism uses three blocks: try, throw, and catch. The try-block must be followed immediately by a handler, which is a catch block. If an exception is thrown in the tryblock, the program control is transferred to the appropriate exception handler.

throw construct
The keyword throw is used to raise an exception when an error is generated in the computation. The throw expression initiates a temporary object of the type T. The syntax of the throw construct is throw T; where, throw is the keyword and T is the named identifier for an exception.

catch construct
The exception handler is indicated by the catch keyword. It must be used immediately after the statements marked by the try keyword. The catch handler can also occur immediately after another catch. Each handler will only evaluate an exception that matches. The syntax of the catch construct is catch ( T ) { // actions for handling an exception } 1.3

try construct
The try keyword defines a boundary within which an exception can occur. A block of code in which an exception can occur must be prefixed by the keyword try. Following the try keyword is a block of code enclosed by braces. This indicates that the program is prepared to test for the existence of exceptions. If an exception occurs, the program flow is interrupted. The syntax of the try construct is try { // code raising exception or referring to a function raising exception } Therefore the sequence of steps in exception handling is 1. 2. 3. 4. Detect the problem causing exception (Hit the exception) Inform that an error has occurred (Throw the exception) Receive the error information (Catch the exception) Take corrective actions (Handle the exception)

Exception handling code resembles the following pattern: my_function( ) { if (operation_fail) throw Object1; } try { //begin of try block .. my_function( ); .. if (overflow) throw object2; } catch (object1) { .. // take corrective actions for operation_fail . } catch (object2) { 1.4

.. // take corrective action for overflow .. } .. Steps performed when an exception is raised are: 1. The program searches for a matching handler 2. If a handler is found, the program control is transferred to that handler. 3. If no handler is found the program will invoke the terminate( ) function. Example: The following program implements exception handling in C ++. #include <iostream.h> #include <process.h> class DIVIDE { }; class RANGE { }; void main( ) { int n1, n2; cout<<Enter two numbers:; cin>>n1>>n2; try { if (n1<0 || n1>100) throw RANGE( ); if (n2==0) throw DIVIDE( ); result = n1 / n2; cout<<result; } catch ( RANGE ) { cout<<Input out of rangeProgram terminated!; exit(1); } catch ( DIVIDE ) { cout<<Divide by zero errorProgram terminated!; exit(1); } }

1.5

In the above program two empty classes RANGE and DIVIDE are defined which will be used for creating temporary objects that will serve as identifiers for the exceptions raised. The number is n1 is to be divided by number n2. But before doing this, we are checking for two conditions. In the first case we check if the number n1 is out of range. If so throw an exception using the statement throw RANGE( ). RANGE( ) is the constructor of the empty class RANGE and when it is invoked, it creates a temporary empty object which is thrown. This object is caught by the catch construct which immediately follows the try construct. In the catch construct, we take corrective measures for the exception raised. In this case we just display an error message and come out of the program. Similarly, we next check if the number n2 is zero. If it so we throw an object of the class DIVIDE which is caught by the respective catch construct and corrective measures are taken. Hence we see that those statements where an unexpected condition may occur, have been enclosed inside the try construct.

DATA STRUCTURES
Data Object: A data object is a set of instances or values. For example, Boolean = { false, true } Digit = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } Letter = { A, B, C,Z, a, b, c..z } In the above examples, Boolean, Digit and Letter are the data objects which are the set of values that are shown within the braces. The values within the braces are called the instances of that particular data object. Consider a data object, Natural Number = { 1, 2, 3, } The instances of this data object may be atomic or compound in nature. The values 1, 2, 3, etc are atomic as they cannot be split further. But take a value 483 which is also an instance of the data object Natural Number. 483 is a compound instance as it can be further split into 4, 8 and 3. These are called the elements of the instance. The elements may be instances of the same data object or it may be the instances of some other data object. The instances of a data object as well as the elements that constitute individual instances are generally related in some way. For example, In the data object Digit, 0 may the smallest number, 1 may be the next number and so on. This is a type of simple relationship. Take the instance 483 of the data object Natural Number. It may be split into 4, 8 and 3, where 4 is the most significant bit, 8 is the next and 3 is the least significant bit. This again is a simple relationship existing between the elements of an instance.

1.6

Hence, now it must be clear that there is always some relationship existing between the instances of a data object and between the elements of the instance. In addition to these relationships, a set of functions is generally associated with a data object. These functions transform one instance of an object into another instance of that object or into an instance of another data object. The function could also create a new instance without transforming the instance from which the new one is created. For example, there can be a function called Add on the instances of a Natural number data object. When Add function is applied on the instances 4 and 5, we get new instance 9 but the original instances 4 and 5 are not disturbed. They still remain in the list of instances of the data object. Data Structure: A Data Structure is a data object together with the relationships that exist among the instances and among the individual elements that compose an instance. In other words, we define Data Structure as a way of organizing data that considers not only the items stored but also their relationship to each other. Once a data structure has been chosen for a particular application, they have to be handled in an efficient way. Hence there comes the necessity of studying Algorithms. The two categories data structures are, 1. Linear Data Structures 2. Non-linear Data Structures Linear data structures are those in which the elements form a sequence whereas nonlinear data structures are those in which the elements do not form a sequence.

LINEAR DATA STRUCTURES


There are two methods by which we can construct a linear data structure. They are, Method 1: By using a sequence of memory locations. These are implemented using arrays. Method 2: By using pointers or links. These are implemented using linked lists. The different types of linear data structures are: 1. Lists The list can be implemented using arrays these are called linear lists or ordered lists. The list can be implemented using pointers these are called linked lists.

2. Stacks - The stacks can be implemented using arrays. - The stacks can be implemented using linked. 3. Queues - The queue can be implemented using arrays. - The queue can be implemented using linked lists. 1.7

LINEAR LIST
Linear List: A Linear list is a data object whose instances are of the form ( e1, e2, en), where n is a finite natural number. ei Element of the list. n length of the list. s size of the element. For example a list of names, list of marks, etc. The operations that are performed on a linear list are, 1. 2. 3. 4. 5. 6. 7. 8. 9. Create a list. Delete a list. Determine whether the list is empty. Determine the length of the list. Find the kth element. Search for a given element. Delete the kth element Insert a new element. Display all elements.

Abstract Data Type (ADT): An Abstract Data Type is a representation in which we provide a specification of the instances as well as of the operations that are to be performed. More precisely, An Abstract Data Type is a data type that is organized in such a way that the specification of the object and the specification of the operation on the object are separated from the representation of the object and the implementation of the operation. Hence an Abstract Data Type representation separates the implementation of the operations from their specification, thus leading the way to object oriented programming. Formula Based Representation: In this method we use an array to represent the instances of an object. Each position of array is called a cell or a node. Individual elements of an instance are located in the array using a mathematical formula as shown. Location (i) = i - 1 (or) Location (i) = i ith element is in position i (if array starts with position one) ith element is in position i-1 (if array starts with position zero)

A Linear list may be specified as an abstract data type (ADT) in which we provide a specification of the instances as well as of the operations that are to be performed. AbstractDataType LinearList { instances ordered finite collection of zero or more elements 1.8

operations Create( ): Create an empty linear list. Destroy( ): Erase the list. IsEmpty( ): Return true if the list is empty, false otherwise. Length( ): Return the list size. Find(k, x): Return kth element of the list in x and return false if not found. Search(x): Return the position of x in the list otherwise return -1 if not found. Delete(k): Delete the kth element. Insert(k, x): Insert x just after kth element Display( ): Display all elements of the list }

LINKED LIST
Linked List: A Linked list is a collection of elements called nodes, each of which stores two items called info and link. Info is an element of the list and a link is a pointer to the next element. The linked list is also called a chain. The different types of Linked lists are, 1. Singly linked list. 2. Doubly linked list 3. Circular linked list

SINGLY LINKED LIST


Singly Linked List: A singly linked list is a linked list in which each node contains only one link pointing to the next node in the list.

In a singly linked list, the first node always pointed by a pointer called HEAD. If the link of the node points to NULL, then that indicates the end of the list. Operations on a singly linked list are, 1. 2. 3. 4. 5. 6. 7. Count the number of elements. Add an element at the beginning of the list. Add an element at the end of the list. Insert an element at the specified position in the list. Delete an element from the list. Search x in the list. Display all the elements of the list. 1.9

The Abstract Data Type of the linked list may be written as shown. AbstractDataType LinkedList { instances finite collection of zero or more elements linked by pointers operations Count( ): Count the number of elements in the list. Addatbeg(x): Add x to the beginning of the list. Addatend(x): Add x at the end of the list. Insert(k, x): Insert x just after kth element. Delete(k): Delete the kth element. Search(x): Return the position of x in the list otherwise return -1 if not found Display( ): Display all elements of the list } Algorithm: Count( ) The first operation count( ) counts the number of elements in the list. Let Head be a pointer pointing to the beginning of the list. If the head points to NULL, then the list is empty. In the count algorithm given below, we first create a temporary pointer Temp and make it point to the node where Head is pointing. Since Head always points to the beginning of the list, Temp is now pointing to the first node in the list. A counter is initialized to zero. The list is traversed using a while loop and every time we move to the next node, the counter is incremented. If Temp doesnt point to NULL, that means the end of the list is not reached and hence temp is made to point to the next node. This is repeated till the end of the list and finally we have the number of elements of the list in the count variable. COUNT( ) Temp = Head Count = 0 While Temp S NULL Count = Count +1 Temp = Link (Temp) End While Return Count End COUNT

1.10

Addatbeg( x ) The operation Addatbeg( x ), adds the element k at the beginning of the existing list. First a temporary pointer is created and made to point to the node where head is pointing. The given element K is stored in a new node. Check if the list is empty. If so make link of new node point to NULL and make Head to point to new, making it the first element of the list. If the list is not empty, then the link of new is made to point to the first element of the existing list and Head is made to point to the new node.

1.11

ADDATBEG( K ) Info(New) = K If Head = NULL Then Link(New) = NULL Else Link(New) = Head Endif Head = New End ADDATBEG Addatend( x ) The operation Addatend( x ), adds the given element x at the end of the existing list. Initially it is checked whether the list is empty or not. If the list is empty then create a new node New and add the value x to the info part of the node. The link part is made to point to NULL. Then the Head is made to point this new node making it the first node. If the list already has some nodes and now a new node is to be added to the end of the list, then create a temporary pointer called Temp and make it to point to the Head initially. Then move the pointer the last node and now create a new node with value x. Make the link part point to NULL. Now the link of temp is made to point to the new node, thus making the new node as the last node of the list.

1.12

ADDATEND( X ) If Head = NULL Info(Temp) = x Link(Temp) = NULL Head = Temp Else Temp = Head While link(Temp) S NULL Temp = link(Temp) End Whjle Info(New) = x Link(New)=NULL Link(Temp) = New Endif End ADDATEND( ) Insert( k, x ) The operation Insert( k, x ) inserts the given element x in the kth position. A temporary pointer Temp is created and made to point to Head. Now the Temp pointer is moved to the k 1 th node. A new node with value x is created and the link of the new node is made to point to the position where the link of temp is pointing. Then the link of temp is made to point to the new node. Thus the given element is inserted in the position k.

1.13

INSERT ( k, x ) Temp = Head I=1 While I < k-1 Temp = link(Temp) I=I+1 End While Info(New) = x Link(New) = Link(Temp) Link(Temp) = New End INSERT( ) Delete ( x ) The operation Delete( x ), deletes the node with value x. The given value x is compared with each node starting from the first node and continued till the last node. If the node to be deleted is the first node, then simply Temp pointer is made to point to Head and then Head is safely moved to point the next node. Now the first node is deleted by deleting the Temp. If the node to be deleted is not the first node, then make it the old node and move the temp pointer to the next node. Check if that is the node to be deleted. If so, make the link of old point to link of temp and delete the node pointed by temp. Now the node pointed by temp can be deleted. If this is also not the node to be deleted then make this old node and move the Temp pointer to the next node and the process is repeated till we reach the last node or the specified node is deleted. DELETE( x ) Temp = Head While Temp S NULL If Info(Temp) = x Then If Temp = Head Then Head = link(Temp) Else Link(old) = Link(Temp) End If Delete Temp Else Old = Temp Temp = Link(Temp) End If End While End DELETE( )

1.14

Search( x ) The operation Search( x ), searches the given value x in the list. If found returns the node position where it is found. A temporary pointer Temp is created and made to point to the Head. Now info part of Temp is compared with the value x. If the value matches the node position number is returned otherwise Temp pointer is moved to the next node. This is repeated till the end of the list is reached or till the element to be searched is found.

1.15

SEARCH( x ) Temp = Head Count = 1 While Temp S NULL If Info(Temp) = x Then Print count End If Count = Count + 1 Temp = Link(Temp) End While End SEARCH( ) Display( ) The operation Display( ), displays all the value in each node of the list. A temporary pointer is created and made to point to Head initially. Now info part of Temp is printed and Temp is moved to the next node. This is repeated till the end of the list is reached. DISPLAY( x ) Temp = Head While Temp S NULL Print Info(Temp) End While End DISPLAY( ) Program //Linked Lists and various operations on it #include <iostream.h> #include <conio.h> class linklist { private: struct node { int data; node *link; }*p; public: linklist(); void addatend(int num); void addatbeg(int num); void insert(int loc, int num); 1.16

int count(); void del(int num); void search(int num); void display(); ~linklist(); }; linklist::linklist() { p=NULL; } void linklist::addatend(int num) { node *temp, *r; if (p==NULL) { temp=new node; temp->data=num; temp->link=NULL; p=temp; } else { temp=p; while (temp->link!=NULL) temp=temp->link; r=new node; r->data=num; r->link=NULL; temp->link=r; } } void linklist::display() { node *temp; temp=p; while(temp!=NULL) { cout<<temp->data<<" "; temp=temp->link; } } linklist::~linklist() { node *temp; while (p!=NULL) { temp=p->link; 1.17

delete p; p=temp; } } void linklist::addatbeg(int num) { node *temp; temp=new node; temp->data=num; temp->link=p; p=temp; } void linklist::insert(int loc, int num) { node *temp, *r; int i=1; temp=p; while (i<loc-1) { temp=temp->link; if (temp==NULL) { cout<<"\nThere are less than "<<loc<<" elements in list"<<endl; return; } i++; } r=new node; r->data=num; r->link=temp->link; temp->link=r; } void linklist::del(int num) { node *old, *temp; temp=p; while (temp!=NULL) { if (temp->data==num) { if (temp==p) p=temp->link; else old->link=temp->link; delete temp; return; } 1.18

else { old=temp; temp=temp->link; } } cout<<"\n\nElement "<<num<<" not found"; } void linklist::search(int num) { node *temp; int count=1; temp=p; while (temp!=NULL) { if (temp->data==num) { cout<<"\nNumber found in position "<<count; return; } else { temp=temp->link; count++; } } cout<<"\nNumber not found"; } int linklist::count() { node *temp; temp=p; int c=0; while (temp!=NULL) { temp=temp->link; c++; } return c; }

void main() { linklist l; clrscr(); l.addatend(100); l.addatend(200); 1.19

l.addatend(300); l.display(); cout<<endl; l.addatend(500); l.display(); cout<<endl; l.addatbeg(50); l.display(); cout<<endl; l.insert(4,1000); l.display(); cout<<endl; l.insert(10,2000); l.display(); cout<<endl; cout<<l.count(); cout<<endl; l.del(300); l.display(); cout<<endl; cout<<l.count(); l.del(35); l.search(1000); l.search(300); getch(); } Output 100 200 300 100 200 300 500 50 100 200 300 500 50 100 200 1000 300 500 There are less than 10 elements in list 50 100 200 1000 300 500 6 50 100 200 1000 500 5 Element 35 not found Number found in position 4 Number not found APPLICATIONS OF LINKED SINGLY LINKED LISTS Set operations using linked lists 1.20

Two lists L1 and L2 are obtained from the user and the set operations such as Union of L1 and L2, and Intersection of L1 and L2 are performed. The program for performing the set operations using singly linked lists is shown. Program: // Set operations on a linked lists --> Union and Intersection #include <iostream.h> #include <conio.h> class linklist { private: struct node { int data; node *link; }; node *head; public: linklist(); ~linklist(); void add(int x); void setunion(linklist &l1, linklist &l2); void setintersection(linklist &l1, linklist &l2); void display(); }; linklist::linklist() { head=NULL; } linklist::~linklist() { node *temp; temp=head; while (head!=NULL) { temp=temp->link; delete head; head=temp; } } void linklist::add(int x) { node *temp, *r, *old; temp=head; 1.21

if (head==NULL || x<head->data) { r=new node; r->data=x; r->link=temp; head=r; } else { while (temp!=NULL) { if (x<temp->data) { r=new node; r->data=x; r->link=temp; old->link=r; return; } else { old=temp; temp=temp->link; } } r=new node; r->data=x; r->link=NULL; old->link=r; } } void linklist::setunion(linklist &l1, linklist &l2) { node *temp1, *temp2, *z; z=NULL; temp1=l1.head; temp2=l2.head; if (temp1==NULL && temp2==NULL) return; while (temp1!=NULL & temp2!=NULL) { if (head==NULL) { head=new node; z=head; } else { z->link=new node; z=z->link; 1.22

} if (temp1->data<temp2->data) { z->data=temp1->data; temp1=temp1->link; } else { if (temp1->data>temp2->data) { z->data=temp2->data; temp2=temp2->link; } else { z->data=temp1->data; temp1=temp1->link; temp2=temp2->link; } } } while (temp1!=NULL) { if (head==NULL) { head=new node; z=head; } else { z->link=new node; z=z->link; } z->data=temp1->data; temp1=temp1->link; } while (temp2!=NULL) { if (head==NULL) { head=new node; z=head; } else { z->link=new node; z=z->link; } z->data=temp2->data; temp2=temp2->link; } 1.23

z->link=NULL; } void linklist::setintersection(linklist &l1, linklist &l2) { node *temp1, *temp2, *z; z=NULL; temp1=l1.head; temp2=l2.head; if (temp1==NULL && temp2==NULL) return; while (temp1!=NULL & temp2!=NULL) { if (temp1->data<temp2->data) { temp1=temp1->link; } else { if (temp1->data>temp2->data) { temp2=temp2->link; } else { if (head==NULL) { head=new node; z=head; } else { z->link=new node; z=z->link; } z->data=temp1->data; temp1=temp1->link; temp2=temp2->link; } } } z->link=NULL; } void linklist::display() { node *temp; temp=head; while (temp!=NULL) 1.24

{ cout<<temp->data<<"\t"; temp=temp->link; } } void main() { clrscr(); linklist l1, l2, l3, l4; l1.add(10); l1.add(200); l1.add(30); l2.add(10); l2.add(80); l2.add(30); l2.add(100); l1.display(); cout<<endl; l2.display(); l3.setunion(l1,l2); cout<<endl; l3.display(); cout<<endl; l4.setintersection(l1,l2); l4.display(); getch(); } Output: 10 10 10 10 30 30 30 30 200 80 80 100 100

200

Addition and Multiplication of Polynomials using operator overloading The polynomials are implemented using the singly linked lists. The nodes in the linked list as usual have a data part and the link part. But the data part here has two sections, one to hold the coefficient of the polynomial term and the other to hold the exponent of the polynomial term. The two polynomials P1 and P2 are obtained from the user and the addition and multiplication of these polynomials are obtained using operator overloading. The + operator is overloaded to polynomial addition and the * operator is overloaded to perform polynomial multiplication. The program for implementing this is given below. Program: // Polynomial Addition and Multiplication using operator overloading 1.25

#include <iostream.h> #include <conio.h> class poly { private: struct node { float c; int e; node *link; }; node *head; public: poly(); void add(float c, int e); void display(); poly operator +(poly &l2); poly operator *(poly &l2); }; poly::poly() { head=NULL; } void poly::add(float c, int e) { node *temp, *r; if (head==NULL) { r=new node; r->c=c; r->e=e; r->link=NULL; head=r; } else { temp=head; while (temp->link!=NULL) temp=temp->link; r=new node; r->c=c; r->e=e; r->link=NULL; temp->link=r; } } poly poly::operator +(poly &l2) 1.26

{ poly ans; node *temp1, *temp2, *z; temp1=head; temp2=l2.head; if (temp1==NULL && temp2==NULL) return ans; while (temp1!=NULL && temp2!=NULL) { if (ans.head==NULL) { ans.head=new node; z=ans.head; } else { z->link=new node; z=z->link; } if (temp1->e>temp2->e) { z->c=temp1->c; z->e=temp1->e; temp1=temp1->link; } else { if (temp2->e>temp1->e) { z->c=temp2->c; z->e=temp2->e; temp2=temp2->link; } else { z->c=temp1->c+temp2->c; z->e=temp1->e; temp1=temp1->link; temp2=temp2->link; } } } while (temp1!=NULL) { if (ans.head==NULL) { ans.head=new node; z=ans.head; } else { 1.27

z->link=new node; z=z->link; } z->c=temp1->c; z->e=temp1->e; temp1=temp1->link; } while (temp2!=NULL) { if (ans.head==NULL) { ans.head=new node; z=ans.head; } else { z->link=new node; z=z->link; } z->c=temp2->c; z->e=temp2->e; temp2=temp2->link; } z->link=NULL; return ans; } poly poly::operator *(poly &l2) { poly prod; node *temp1, *temp2, *z; temp1=head, temp2=l2.head; if (temp1==NULL && temp2==NULL) return prod; while (temp1!=NULL) { temp2=l2.head; poly ans; while (temp2!=NULL) { if (ans.head==NULL) { ans.head=new node; z=ans.head; } else { z->link=new node; z=z->link; 1.28

} z->c=temp1->c*temp2->c; z->e=temp1->e+temp2->e; temp2=temp2->link; } z->link=NULL; prod=prod+ans; temp1=temp1->link; } return prod; } void poly::display() { node *temp; int f=0; temp=head; while (temp!=NULL) { if (f!=0) { if (temp->c>0) cout<<"+"; } if (temp->e!=0) cout<<temp->c<<"X^"<<temp->e; else cout<<temp->c; temp=temp->link; f=1; } } void main() { clrscr(); poly p1, p2, p3, p4; p1.add(5,4); p1.add(3,2); p1.add(1,0); p1.display(); p2.add(6,2); p2.add(9,0); cout<<endl; p2.display(); p3=p1+p2; cout<<endl; p3.display(); cout<<endl; p4=p1*p2; p4.display(); 1.29

getch(); } Output: 5X^4+3X^2+1 6X^2+9 5X^4+9X^2+10 30X^6+63X^4+33X^2+9

CIRCULAR LINKED LIST


Circular Linked List: Circular linked list is a linked list which consists of collection of nodes each of which has two parts, namely the data part and the link part. The data part holds the value of the element and the link part has the address of the next node. The last node of list has the link pointing to the first node thus making the circular traversal possible in the list. Logical representation of the circular linked list:

DOUBLY LINKED LIST


Doubly linked list: The Doubly linked list is a collection of nodes each of which consists of three parts namely the data part, prev pointer and the next pointer. The data part stores the value of the element, the prev pointer has the address of the previous node and the next pointer has the value of the next node.

In a doubly linked list, the head always points to the first node. The prev pointer of the first node points to NULL and the next pointer of the last node points to NULL. Operations on a Doubly linked list are, 1. Count the number of elements. 2. Add an element at the beginning of the list. 3. Add an element at the end of the list. 4. Insert an element at the specified position in the list. 5. Delete an element from the list. 6. Display all the elements of the list. 1.30

The Abstract Data Type of the linked list may be written as shown. AbstractDataType DoublyLinkedList { instances finite collection of zero or more elements linked by two pointers, one pointing the previous node and the other pointing to the next node. operations Count( ): Count the number of elements in the list. Addatbeg(x): Add x to the beginning of the list. Addatend(x): Add x at the end of the list. Insert(k, x): Insert x just after kth element. Delete(k): Delete the kth element. Search(x): Return the position of x in the list otherwise return -1 if not found Display( ): Display all elements of the list } Algorithm: The operations count( ), Search(x) and Delete(x) are similar to that of the singly linked list. Addatbeg(x) The operation Addatbeg(x) adds a given element x at the beginning of the list. A new node R is created and the value x is store in the data part of R. The prev pointer of R is made to point to NULL and the next pointer is made to point to head. Then the prev pointer of head is made to point to R and head is now moved to point to R making it the first node. Thus the new node is added at the beginning of the doubly linked list. ADDATBEG(x) Info(R) = x Prev(R) = NULL Next(R) = head Prev(head) = R Head = R End ADDATBEG( )

1.31

Addatend(x) The Addatend(x) operation adds the given element x at the end of the doubly linked list. If the given list is empty then create a new node R and store the value of x in the data part of R. Now make the prev pointer and the next pointer of R point to NULL. Then head is pointed to R. If the list already contains some elements then, a temporary pointer is created and made to point to head. The temp pointer is now moved to the last node and then a new node R is created. The value x is stored in the data part of R and next pointer of R is made to point to NULL. The prev pointer of R is made to point to temp and next pointer of Temp is made to point to R. Thus the new node is added at the end of the doubly linked list. ADDATEND(x) If head = NULL Then Info(R) = x Next(R) = NULL Prev(R) = NULL Head = R Else Temp = head 1.32

While next(temp) S NULL Temp = next(temp) End While Info(R) = x Next(R) = NULL Prev(R) = Temp Next(Temp) = R End If End ADDATEND( )

Insert(x, k) The Insert(x) operation inserts a given element x at the specified position k. A temporary pointer is created and made to point to head. Then it is moved to the k-1th node. Now a new node R is created and the data part is stored with value of x. The next pointer of R is made to point to next(temp) and the prev pointer of next(temp) is made to point to R. Thus the links on the right side of the new node is established. Now the next of Temp is made to point to R and the prev pointer of R is made to point to temp thus establishing the links on the left side of the new node. Now the new node is inserted at the position k.

1.33

INSERT(x, k) Temp = head I=1 While I < k -1 Temp = next (temp) I=I+1 End while Next(R) = Next(temp) Prev(Next(Temp) = R Next(Temp) = R Prev(R) = Temp End INSERT( ) Delete(x) The Delete(x) operation deletes the element x from the doubly linked list. A temporary pointer is created and made to point to head. Now the data of temp is compared with x and if it matches that is the node to be deleted otherwise move to the next node and again compare. If the node to be deleted is first node, then prev(next(temp)) is made to point to NULL and head is pointed to next(temp). The node pointed by temp is deleted. When the node to be deleted is not the first node, then next(prev(temp)) is made to point to next(temp) and prev(next(temp)) is made to point to prev(temp). The node pointed by temp is deleted. 1.34

DELETE(x) Temp = head While temp S NULL If x = info(temp) Then If head = temp Then Prev(next(temp) = NULL Head = next(temp) Delete temp Else Prev(next(temp)) = prev(temp) Next(prev(temp))= next(temp) Delete temp End if Else Temp = next(temp) End if End while End DELETE( ) Program 1.35

//Doubly linked list and the various operations on it #include <iostream.h> #include <conio.h> class dlink { private: struct node { node *prev; int data; node *next; }; node *head; public: dlink(); ~dlink(); void addatbeg(int x); void addatend(int x); void insert(int x, int k); void del(int x); void display(); }; dlink::dlink() { head=NULL; } dlink::~dlink() { node *temp; while (head!=NULL) { temp=head->next; delete head; head=temp; } } void dlink::display() { node *temp; temp=head; while (temp!=NULL) { cout<<temp->data<<"\t"; temp=temp->next; } } 1.36

void dlink::addatbeg(int x) { node *r; r=new node; r->data=x; r->prev=NULL; r->next=head; head=r; } void dlink::addatend(int x) { node *temp, *r; temp=head; while (temp->next!=NULL) temp=temp->next; r=new node; r->data=x; r->prev=temp; r->next=NULL; temp->next=r; } void dlink::insert(int x, int k) { node *temp, *r; temp=head; int i=1; while (i<k-1) temp=temp->next; r=new node; r->data=x; r->next=temp->next; temp->next->prev=r; r->prev=temp; temp->next=r; } void dlink::del(int x) { node *temp; temp=head; while (temp!=NULL) { if (temp->data==x) { if (head==temp) { temp->next->prev=NULL; head=temp->next; 1.37

delete temp; } else { temp->prev->next=temp->next; temp->next->prev=temp->prev; delete temp; } } else temp=temp->next; } } void main() { clrscr(); dlink d1; d1.addatbeg(50); d1.addatbeg(60); d1.addatbeg(100); d1.display(); d1.addatend(30); cout<<endl; d1.display(); d1.insert(25,2); cout<<endl; d1.display(); d1.del(60); cout<<endl; d1.display(); d1.del(100); cout<<endl; d1.display(); getch(); } Output: 100 60 50 100 60 50 30 100 25 60 50 30 100 25 50 30 25 50 30 APPLICATIONS OF DOUBLY LINKED LISTS Payroll Processing using Doubly Linked Lists 1.38

The Doubly linked lists are used, when two way traversal should be possible so that the searching process is faster. Payroll processing of employees can be done where the input is the employee id and the output is the pay details of the employee. The following program implements the payroll processing using doubly linked lists. Program: //Doubly linked list and the various operations on it #include <iostream.h> #include <conio.h> class dlink { private: struct node { node *prev; int id; char name[25]; float basic; node *next; }; node *head; public: dlink(); ~dlink(); void addatbeg(int x); void addatend(int x); void insert(int x, int k); void del(int x); void display(); void payroll(int x); }; dlink::dlink() { head=NULL; } dlink::~dlink() { node *temp; while (head!=NULL) { temp=head->next; delete head; head=temp; } } 1.39

void dlink::display() { node *temp; temp=head; cout<<"Employee ID\tEmployee Name\tBasic Salary\n\n"; while (temp!=NULL) { cout<<temp->id<<"\t\t"<<temp->name<<"\t\t"<<temp->basic<<"\n"; temp=temp->next; } } void dlink::addatbeg(int x) { node *r; r=new node; cout<<"Name:"; cin>>r->name; cout<<"Basic:"; cin>>r->basic; r->id=x; r->prev=NULL; r->next=head; head=r; } void dlink::addatend(int x) { node *temp, *r; temp=head; while (temp->next!=NULL) temp=temp->next; r=new node; r->id=x; cout<<"Name:"; cin>>r->name; cout<<"Basic:"; cin>>r->basic; r->prev=temp; r->next=NULL; temp->next=r; } void dlink::insert(int x, int k) { node *temp, *r; temp=head; int i=1; while (i<k-1) temp=temp->next; 1.40

r=new node; r->id=x; cout<<"Name:"; cin>>r->name; cout<<"Basic:"; cin>>r->basic; r->next=temp->next; temp->next->prev=r; r->prev=temp; temp->next=r; } void dlink::del(int x) { node *temp; temp=head; while (temp!=NULL) { if (temp->id==x) { if (head==temp) { temp->next->prev=NULL; head=temp->next; delete temp; } else { temp->prev->next=temp->next; temp->next->prev=temp->prev; delete temp; } } else temp=temp->next; } } void dlink::payroll(int x) { node *temp; temp=head; float hra, cca, da, net; while (temp!=NULL) { if (temp->id==x) { cout<<"\n\n--------PAYROLL-----------------\n\n"; cout<<"\nEmployee Id\t:\t"<<x; cout<<"\nEmployee Name\t:\t"<<temp->name; 1.41

cout<<"\nBasic\t\t:\t"<<temp->basic; hra=temp->basic*0.12; cca=temp->basic*0.05; da=temp->basic*0.60; net=temp->basic+hra+cca+da; cout<<"\nHRA\t\t:\t"<<hra; cout<<"\nCCA\t\t:\t"<<cca; cout<<"\nDA\t\t:\t"<<da; cout<<"\nNet Salary\t:\t"<<net; return; } else temp=temp->next; } } void main() { clrscr(); dlink d1; d1.addatbeg(50); d1.addatbeg(60); d1.addatbeg(100); d1.addatend(30); d1.insert(25,2); cout<<endl; d1.display(); d1.del(100); cout<<endl; d1.display(); cout<<endl; d1.payroll(60); getch(); } Output: Name:Sugumaran Basic:6000 Name:Rajesh Basic:7000 Name:Kumar Basic:4000 Name:Ganesh Basic:9000 Name:Richard Basic:8000 Employee ID Employee Name Basic Salary 1.42

100 25 60 50 30 Employee ID 25 60 50 30

Kumar Richard Rajesh Sugumaran Ganesh

4000 8000 7000 6000 9000

Employee Name Basic Salary Richard Rajesh Sugumaran Ganesh 8000 7000 6000 9000

--------PAYROLL----------------Employee Id : Employee Name : Basic : HRA : CCA : DA : Net Salary : 60 Rajesh 7000 840 350 4200 12390

STACKS
The data structures seen so far, allows insertion and deletion of elements at any place. But sometimes it is required to permit the addition and deletion of elements only at one end that is either at the beginning or at the end. Stacks: A stack is a data structure in which addition of new element or deletion of an existing element always takes place at the same end. This end is often known as top of stack. When an item is added to a stack, the operation is called push, and when an item is removed from the stack the operation is called pop. Stack is also called as Last-InFirst-Out (LIFO) list. Operations on Stack: There are two possible operations done on a stack. They are pop and push operation. Push: Allows adding an element at the top of the stack. Pop: Allows removing an element from the top of the stack.

The Stack can be implemented using both arrays and linked lists. When dynamic memory allocation is preferred we go for linked lists to implement the stacks. ARRAY IMPLEMENTATION OF THE STACK Push operation: 1.43

If the elements are added continuously to the stack using the push operation then the stack grows at one end. Initially when the stack is empty the top = -1. The top is a variable which indicates the position of the topmost element in the stack.

PUSH(x) If top = MAX 1 Then Print Stack is full Return Else Top = top + 1 A[top] = x End if End PUSH( ) Pop operation: On deletion of elements the stack shrinks at the same end, as the elements at the top get removed.

POP( ) If top = -1 Then Print Stack is empty Return 1.44

Else Item = A[top] A[Top] = 0 Top = top 1 Return item End if End POP( ) If arrays are used for implementing the stacks, it would be very easy to manage the stacks. However, the problem with an array is that we are required to declare the size of the array before using it in a program. This means the size of the stack should be fixed. We can declare the array with a maximum size large enough to manage a stack. As result, the stack can grow or shrink within the space reserved for it. The following program implements the stack using array. Program: // Stack and various operations on it #include <iostream.h> #include <conio.h> const int MAX=20; class stack { private: int a[MAX]; int top; public: stack(); void push(int x); int pop(); void display(); }; stack::stack() { top=-1; } void stack::push(int x) { if (top==MAX-1) { cout<<"\nStack is full!"; return; } else { 1.45

top++; a[top]=x; } } int stack::pop() { if (top==-1) { cout<<"\nStack is empty!"; return NULL; } else { int item=a[top]; top--; return item; } } void stack::display() { int temp=top; while (temp!=-1) cout<<"\n"<<a[temp--]; } void main() { clrscr(); stack s; int n; s.push(10); s.push(20); s.push(30); s.push(40); s.display(); n=s.pop(); cout<<"\nPopped item:"<<n; n=s.pop(); cout<<"\nPopped item:"<<n; s.display(); getch(); } Output: 40 30 20 10 1.46

Popped item:40 Popped item:30 20 10 LINKED LIST IMPLEMENTATION OF STACK Initially, when the stack is empty, top points to NULL. When an element is added using the push operation, top is made to point to the latest element whichever is added. Push operation: Create a temporary node and store the value of x in the data part of the node. Now make link part of temp point to Top and then top point to Temp. That will make the new node as the topmost element in the stack.

PUSH(x) Info(temp) = x Link(temp) = top Top = temp End PUSH( ) Pop operation The data in the topmost node of the stack is first stored in a variable called item. Then a temporary pointer is created to point to top. The top is now safely moved to the next node below it in the stack. Temp node is deleted and the item is returned.

1.47

POP( ) If Top = NULL Then Print Stack is empty Return Else Item = info(top) Temp = top Top = link(top) Delete temp Return item End if End POP( ) The following program implements the stack using linked lists. Program: // Stack implemented using linked list #include <iostream.h> #include <conio.h> class stack { private: struct node { int data; node *link; }; node *top; public: stack(); 1.48

~stack(); void push(int x); int pop(); void display(); }; stack::stack() { top=NULL; } stack::~stack() { node *temp; while (top!=NULL) { temp=top->link; delete top; top=temp; } } void stack::push(int x) { node *temp; temp=new node; temp->data=x; temp->link=top; top=temp; } int stack::pop() { if (top==NULL) { cout<<"\nStack is empty!"; return NULL; } node *temp=top; int item=temp->data; top=temp->link; delete temp; return item; } void stack::display() { node *temp=top; while (temp!=NULL) { cout<<"\n"<<temp->data; 1.49

temp=temp->link; } } void main() { clrscr(); stack s; int n; s.push(10); s.push(20); s.push(30); s.push(40); s.display(); n=s.pop(); cout<<"\nPopped item:"<<n; n=s.pop(); cout<<"\nPopped item:"<<n; s.display(); getch(); } Output: 40 30 20 10 Popped item:40 Popped item:30 20 10 APPLICATION OF STACKS Conversion of Infix Expression to Postfix Expression The stacks are frequently used in evaluation of arithmetic expressions. An arithmetic expression consists of operands and operators. The operands can be numeric values or numeric variables. The operators used in an arithmetic expression represent the operations like addition, subtraction, multiplication, division and exponentiation. The arithmetic expression expressed in its normal form is said to be Infix notation, as shown: A+B The above expression in prefix form would be represented as follows: 1.50

+ AB The same expression in postfix form would be represented as follows: AB + Hence the given expression in infix form is first converted to postfix form and then evaluated to get the results. The function to convert an expression from infix to postfix consists following steps: 1. Every character of the expression string is scanned in a while loop until the end of the expression is reached. 2. Following steps are performed depending on the type of character scanned. (a) If the character scanned happens to be a space then that character is skipped. (b) If the character scanned is a digit or an alphabet, it is added to the target string pointed to by t. (c) If the character scanned is a closing parenthesis then it is added to the stack by calling push( ) function. (d) If the character scanned happens to be an operator, then firstly, the topmost element from the stack is retrieved. Through a while loop, the priorities of the character scanned and the character popped opr are compared. Then following steps are performed as per the precedence rule. i. If opr has higher or same priority as the character scanned, then opr is added to the target string. ii. If opr has lower precedence than the character scanned, then the loop is terminated. Opr is pushed back to the stack. Then, the character scanned is also added to the stack. (e) If the character scanned happens to be an opening parenthesis, then the operators present in the stack are retrieved through a loop. The loop continues till it does not encounter a closing parenthesis. The operators popped, are added to the target string pointed to by t. 3. Now the string pointed by t is the required postfix expression. Program: // Program to convert an Infix form to Postfix form #include <iostream.h> #include <string.h> #include <ctype.h> #include <conio.h> const int MAX=50; class infix { private: 1.51

char target[MAX], stack[MAX]; char *s, *t; int top; public: infix(); void push(char c); char pop(); void convert(char *str); int priority (char c); void show(); }; infix::infix() { top=-1; strcpy(target,""); strcpy(stack,""); t=target; s=""; } void infix::push(char c) { if (top==MAX-1) cout<<"\nStack is full\n!"; else { top++; stack[top]=c; } } char infix::pop() { if (top==-1) { cout<<"\nStack is empty\n"; return -1; } else { char item=stack[top]; top--; return item; } } void infix::convert(char *str) { 1.52

s=str; while(*s!='\0') { if (*s==' '||*s=='\t') { s++; continue; } if (isdigit(*s) || isalpha(*s)) { while(isdigit(*s) || isalpha(*s)) { *t=*s; s++; t++; } } if (*s=='(') { push(*s); s++; } char opr; if (*s=='*'||*s=='+'||*s=='/'||*s=='%'||*s=='-'||*s=='^') { if (top!=-1) { opr=pop(); while (priority(opr)>=priority(*s)) { *t=opr; t++; opr=pop(); } push(opr); push(*s); } else push (*s); s++; } if (*s==')') { opr=pop(); while ((opr)!='(') { *t=opr; t++; opr=pop(); } 1.53

s++; } } while (top!=-1) { char opr=pop(); *t=opr; t++; } *t='\0'; } int infix::priority(char c) { if (c=='^') return 3; if (c=='*'||c=='/'||c=='%') return 2; else { if (c=='+'||c=='-') return 1; else return 0; } } void infix::show() { cout<<target; } void main() { clrscr(); char expr[MAX], *res[MAX]; infix q; cout<<"\nEnter an expression in infix form: "; cin>>expr; q.convert(expr); cout<<"\nThe postfix expression is: "; q.show(); getch(); } 1.54

Output: Enter an expression in infix form: 5^2-5 Stack is empty The postfix expression is: 52^5Evaluation of Expression entered in postfix form The program takes the input expression in postfix form. This expression is scanned character by character. If the character scanned is an operand, then first it is converted to a digit form and then it is pushed onto the stack. If the character scanned is a blank space, then it is skipped. If the character scanned is an operator, then the top two elements from the stack are retrieved. An arithmetic operation is performed between the two operands. The type of arithmetic operation depends on the operator scanned from the string s. The result is then pushed back onto the stack. These steps are repeated as long as the string s is not exhausted. Finally the value in the stack is the required result and is shown to the user. Program: // Program to evaluate an expression entered in postfix form #include <iostream.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <conio.h> const int MAX=50; class postfix { private: int stack[MAX]; int top, n; char *s; public: postfix(); void push(int item); int pop(); void calculate(char *str); void show(); }; postfix::postfix() 1.55

{ top=-1; } void postfix::push(int item) { if (top==MAX-1) cout<<endl<<"Stack is full"; else { top++; stack[top]=item; } } int postfix::pop() { if (top==-1) { cout<<endl<<"Stack is empty"; return NULL; } int data=stack[top]; top--; return data; } void postfix::calculate(char *str) { s=str; int n1, n2, n3; while (*s) { if (*s==' '||*s=='\t') { s++; continue; } if (isdigit(*s)) { n=*s-'0'; push(n); } else { n1=pop(); n2=pop(); switch(*s) { case '+': n3=n2+n1; break; 1.56

case '-': n3=n2-n1; break; case '/': n3=n2/n1; break; case '*': n3=n2*n1; break; case '%': n3=n2%n1; break; case '^': n3=pow(n2, n1); break; default: cout<<"Unknown operator"; exit(1); } push(n3); } s++; } } void postfix::show() { n=pop(); cout<<"Result is: "<<n; } void main() { clrscr(); char expr[MAX]; cout << "\nEnter postfix expression to be evaluated : "; cin>>expr; postfix q ; q.calculate(expr); q.show(); getch(); } Output: Enter postfix expression to be evaluated : 53^5Result is: 120

QUEUE
Queue: Queue is a linear data structure that permits insertion of new element at one end and deletion of an element at the other end. The end at which the deletion of an element take place is called front, and the end at which insertion of a new element can take place 1.57

is called rear. The deletion or insertion of elements can take place only at the front or rear end of the list respectively. The first element that gets added into the queue is the first one to get removed from the list. Hence, queue is also referred to as First-In-First-Out list (FIFO). Queues can be represented using both arrays as well as linked lists. ARRAY IMPLEMENTATION OF QUEUE If queue is implemented using arrays, the size of the array should be fixed maximum allowing the queue to expand or shrink. Operations on a Queue There are two common operations one in a queue. They are addition of an element to the queue and deletion of an element from the queue. Two variables front and rear are used to point to the ends of the queue. The front points to the front end of the queue where deletion takes place and rear points to the rear end of the queue, where the addition of elements takes place. Initially, when the queue is full, the front and rear is equal to -1. Add(x) An element can be added to the queue only at the rear end of the queue. Before adding an element in the queue, it is checked whether queue is full. If the queue is full, then addition cannot take place. Otherwise, the element is added to the end of the list at the rear side.

ADDQ(x) If rear = MAX 1 Then Print Queue is full Return Else Rear = rear + 1 A[rear] = x If front = -1 Then Front = 0 End if End if End ADDQ( ) 1.58

Del( ) The del( ) operation deletes the element from the front of the queue. Before deleting and element, it is checked if the queue is empty. If not the element pointed by front is deleted from the queue and front is now made to point to the next element in the queue.

DELQ( ) If front = -1 Then Print Queue is Empty Return Else Item = A[front] A[front] = 0 If front = rear Then Front = rear = -1 Else Front = front + 1 End if Return item End if End DELQ( ) Program: // Queues and various operations on it Using arrays #include <iostream.h> #include <conio.h> const int MAX=10; class queue { private: int a[MAX], front, rear; public: queue(); void addq(int x); int delq(); void display(); }; 1.59

queue::queue() { front=rear=-1; } void queue::addq(int x) { if (rear==MAX-1) { cout<<"Queue is full!"; return; } rear++; a[rear]=x; if (front==-1) front=0; } int queue::delq() { if (front==-1) { cout<<"Queue is empty!"; return NULL; } int item=a[front]; a[front]=0; if (front==rear) front=rear=-1; else front++; return item; } void queue::display() { if (front==-1) return; for (int i=front; i<=rear; i++) cout<<a[i]<<"\t"; } void main() { clrscr(); queue q; q.addq(50); q.addq(40); q.addq(90); q.display(); 1.60

cout<<endl; int i=q.delq(); cout<<endl; cout<<i<<" deleted!"; cout<<endl; q.display(); i=q.delq(); cout<<endl; cout<<i<<" deleted!"; cout<<endl; i=q.delq(); cout<<i<<" deleted!"; cout<<endl; i=q.delq(); getch(); } Output: 50 40 90

50 deleted! 40 90 40 deleted! 90 deleted! Queue is empty! LINKED LIST IMPLEMENTATION OF QUEUE Queue can be represented using a linked list. Linked lists do not have any restrictions on the number of elements it can hold. Space for the elements in a linked list is allocated dynamically; hence it can grow as long as there is enough memory available for dynamic allocation. The queue represented using linked list would be represented as shown. The front pointer points to the front of the queue and rear pointer points to the rear of the queue.

Addq(x) In linked list representation of queue, the addition of new element to the queue takes place at the rear end. It is the normal operation of adding a node at the end of a list. ADDQ(x) 1.61

If front = NULL Then Rear = front = temp Return End if Link(rear) = temp Rear = link(rear) End ADDQ( ) Delq( ) The delq( ) operation deletes the first element from the front end of the queue. Initially it is checked, if the queue is empty. If it is not empty, then return the value in the node pointed by front, and moves the front pointer to the next node. DELQ( ) If front = NULL Print Queue is empty Return Else While front S NULL Temp = front Front = link(front) Delete temp End while End if End DELQ( ) Program: // Queue implemented using linked lists #include <iostream.h> #include <conio.h> class queue { private: struct node { int data; node *link; }; node *front, *rear; public: queue(); ~queue(); 1.62

void addq(int x); int delq(); void display(); }; queue::queue() { front=rear=NULL; } queue::~queue() { node *temp; while (front!=NULL) { temp=front->link; delete front; front=temp; } } void queue::addq(int x) { node *temp; temp=new node; temp->data=x; temp->link=NULL; if (front==NULL) front=rear=temp; else { rear->link=temp; rear=temp; } } int queue::delq() { int item; node *temp; if (front==NULL) { cout<<"Queue is empty!"; return NULL; } temp=front->link; item=front->data; delete front; front=temp; return item; } 1.63

void queue::display() { node *temp; temp=front; while (temp!=NULL) { cout<<temp->data<<"\t"; temp=temp->link; } } void main() { clrscr(); queue q; q.addq(50); q.addq(40); q.addq(90); q.display(); cout<<endl; int i=q.delq(); cout<<endl; cout<<i<<" deleted!"; cout<<endl; q.display(); i=q.delq(); cout<<endl; cout<<i<<" deleted!"; cout<<endl; i=q.delq(); cout<<i<<" deleted!"; cout<<endl; i=q.delq(); getch(); } Output: 50 40 90

50 deleted! 40 90 40 deleted! 90 deleted! Queue is empty! APPLICATION OF QUEUE 1.64

Implementation of Circular queue for Round Robin Algorithm In a Round Robin algorithm, the list is traversed in only one direction. The traversal can be from one value to the next. But when the last value is reached, the control goes to the first value and the process repeats. This Round Robin algorithm can be implemented using circular queue as shown.

Program: // Circular queue and various operations on it #include <iostream.h> #include <conio.h> const int MAX=10; class cqueue { private: int a[MAX], front, rear; public: cqueue(); void addq(int x); int delq(); void display(); }; cqueue::cqueue() { front=rear=-1; for (int i=0; i<MAX; i++) a[i]=0; } void cqueue::addq(int x) { if (front==0 && rear==MAX-1) 1.65

{ cout<<"\nQueue is full!"; return; } if (rear==MAX-1) rear=0; else rear++; a[rear]=x; if (front==-1) front=0; } int cqueue::delq() { if (front==-1) { cout<<"\nQueue is empty!"; return NULL; } int item=a[front]; a[front]=0; if (front==rear) front=rear=-1; else front++; return item; } void cqueue::display() { if (front==-1) return; for (int i=0; i<MAX; i++) cout<<a[i]<<"\t"; } void main() { clrscr(); cqueue q; q.addq(90); q.addq(50); q.addq(40); int i=q.delq(); i=q.delq(); q.addq(90); q.display(); cout<<endl; i=q.delq(); cout<<endl; 1.66

cout<<i<<" deleted!"; cout<<endl; q.display(); i=q.delq(); q.display(); getch(); } Output: 0 0 40 90 90 0 0 0 0 0 0 0 0 0 0 0 0

40 deleted! 0 0 0

-------End of Unit I-------

1.67

Das könnte Ihnen auch gefallen