You are on page 1of 99

Preface

Until today no book is available in the market strictly according to JNTU syllabi. This
is the first book to cover entire syllabus for both CSE and IT branches. The book
provides an introduction to object oriented programming through C++ language.

Highlights of the book:

1. Overview of C++ language basic features.


2. Introduction to object orient design concepts.
3. Comprehensive coverage of all data structures including dictionaries, priority
queues etc .
4. Implementation details of data structures in C++.
5. Covers pattern matching algorithms.
6. C++ code for important algorithms.

Prerequisites

This book is mainly intended for the students of B.Tech second year who are
normally familiar with Data Structure using C and familiar with basic concepts of C+
+.

About the Author


Chapter 1: Introduction to C++:

C++ is an object oriented language developed in 1980’s


by Bjarne Stroustrup at AT&T Bell laboratories, New Jersy. He
completed his doctoral program from Cambridge University.
Presently he is working as Professor in Computer Science at
Texas A&M University. He had combined the Simula 's use
of classes and object-oriented features with the power
and efficiency of C to develop C ++.

1.1 History:

It is the enhanced version of C language. The term C++ was first used in 1983. Initially
it was name as C with classes. In 1983 it was named as C++(++ stands for
increment representing enhancement of C language as C++). C++ is a super set
containing all features of C and adds on classes, function overloading and operator
overloading.

Some OOP Languages and Concepts


1.2 Advantages of C++ over C:

1. It is object oriented.
1.3 Advantages of C++ over Java:

1. Provides stronger compile time type checking.


2. Provides compile time polymorphism through templates.
3. Provides run time polymorphism through virtual functions.
4. Includes pointers.
5. Explicit control over destruction of class objects.

1.4 Structure of C++ program:

Like C, C++ program also has a main function main (), which returns an
integer to operating system. Comments can be included in // or /*. After comments
preprocessor directives can be included with # symbol. Before main in C++, class
declaration, class function definitions must appear.

/* comments */

# preprocessor statements

class declaration

class functions

main()
{
}

Ex:

/* This is c++ program */

#include <iostream.h>

class complex
{
private:
int real;
int img;
public:
add();
};

Void complex :: add()


{
complex x,y,z;
cin>>x.real,x.img,y.ral,y.img;
z.real=x.real+y.real;
z.img=x.img+y.img;
cout<<z.real,z.img;
}

1.5 Character Set of C++:

There are two character sets in C++ language. They are – Source character set
and Execution characters or escape sequence characters.

a) Source Characters:
These characters are used to create source text. They are

1. Alphabets – A to Z, a to z
2. Digits – 0 to 9
3. Special characters+,_,),(,*,&,^,%,$,#,!,[],?,’,;,:,\,/,~etc.

a) Execution Characters:

These characters are interpreted at the time of execution. The escape


sequence characters are represented by backslash followed by a character.

\0 end of string
\n end of line
\r carriage return
\f form feed
\v vertical tab
\b back space
\t horizontal tab
\a alert
\\ back slash

1.6 C++ Tokens:

A token is a group of characters in source program that is recognized by


compiler as predefined class. There are five types of tokens, they are keywords,
identifiers, constants, special characters and operators.

Keywords:

C++ has standard identifiers called keywords. Keywords have a predefined


meaning and they must be used for that purpose only. The key words supported by
C & C++ are

Auto double int instruct


Break else long switch
Case enum register typedef
Char extern return union
Const float short unsigned
Continue for signed void
Default goto sizeof volatile
Do if static while

In addition to these C++ supports the following key words

Asm friend private this static


Catch inline protected throw dynamic
Class new public virtual overload
Delete operators template try type

Identifier:

An identifier is a name assigned to variables, arrays, functions classes etc.


An identifier must start with a letter and may have letters, digits and underscore.
There is no limit on the length of the identifier.

Constants:

C++ provides three types of constants. They are Numeric constants,


character constants and string constants.
Numeric constants are integer constants and floating point constants having both
positive and negative numbers.

Character constants are characters included in single quotes.

String constants are alphanumeric characters included in double quotes.

A symbolic constant can be created in C++ y using a qualifier const or by


using enum keyword. Constants declared by using const are global. They can be
made local by declaring them as static.

1.7 Data Types in C++:

The data types supported by C++ can be divided into 3 categories. They are
built in data type, derived data type and user defined data type.

Built in type:

Again built in data type is classified into three type. They are integral type,
floating type and void type.

1. Integral type is divided into, integer and char type.


2. Floating type is divided into float type and double type.
3. Void type is used to specify the return value of a function is 0.

A part form these modifiers are used with integral and floating data types,
such
as signed, unsigned, long short etc.

character type:
char 1 -128 to 127
unsigned char 1 0 to 255
signed char 1 -128 to 127

Integer type:
Int 2 -32768 to 32767
Unsigned int 2 0 to 65535
Signed int 2 -32768 to 32767
Short int 2 -32768 to 32767
Unsigned short int 2 0 to 65535
Signed short int 2 -32768 to 32767
Long int 4 -2147483648 to 2147483647
Unsigned long int 4 0 to 4294967295
Signed short int 4 -2147483648 to 2147483647

Float type:
Float 4 3.4E-38 to 3.4E+38
Double 8 1.7E-308 to 1.7E+308
Long Double 10 3.4E-4932 to 1.1E+4932

Derived data types:

Derived data type is a data type constructed by the help of built in data type
such as int, char and float. These are arrays, functions and pointers.

Arrays:

These are similar to the arrays used in C. Only difference is while using char
arrays, the size of the char array must be greater one larger than actual characters
present to make room for null character.

Ex: char s[5] = “rama”;

Pointers:

C++ supports all type of pointers that are supported by C. In addition it also
supports pointer to constant or constant pointer.

Ex: char *p= “x”;


Int *p = &x;

User defined data type:

A part form structures and unios supported by C, C++ also supports classes
and enumerated data type.

Class: A class is a data type used to declare variables. It is generalization of


different objects having similar properties. The class variables are known as objects.

Enumerated data type: It is used to attach names to numbers. A keyword enum is


used to enumerate a list of words by values 0,1,2 etc.

Ex: enum shape {circle, square, triangle};


Enum flag {off, on};
Enum color {red, blue=4, green};

1.8 Dynamic Initialization:

In C all the variables must be defined at the beginning of a scope i.e before
the procedure. Therefore compiler must move back and forth in the program to see
whether a variable has been declared or not. This makes a lot of wastage of time.
Thus C++ allows to declare the variable anywhere in the scope. A variable can be
declared at the place where it is first used.

Ex: main()
{
int a,b;
a=4, b=5;
int c=a+b;
coutt<<c;
}

Also C++ allows to declare and initialize a variable simultaneously at the


place where it is used first time. This is known as dynamic initialization.

Ex: float avg = sum/n;

Reference Variables:

A reference variable provides an alternative name to the previously defined


variable. A reference variable must be initialized at the time of declaration. A
reference variable can be created by

Data type & reference name = variable name

Ex: int x =5;


Int & a = x; now both x and a are same. Both the variables refer to the same
data object.

These are mainly used to pass arguments to functions. This type of calling
functions in known as call by reference. This property is required in object oriented
programming, because parameter of objects are copied back an forth.

1.9 Operators in C++:

Operators supported by C++ are classified into 5 groups. They are

1. Arithmetic Operators: These are used to perform arithmetic operations.

+ addition
– subtraction
* multiplication
/ division
% modulus

1. Assignment Operators: These are used to store the value of the expression
on the right hand side.

These operators are used to form assignment expressions which assign the
value of an expression to an identifier. They are

a) = is used to assign a value to a variable. It two operands of different types


are used with this operator, the value of operand in right hand side is
automatically converted to the type of operand in left.
General form
Identifier = expression

Ex: int 1=3.5, then the value of l is equal to 3.

b) + = is used to add the previous value of expression in the left side to the
right side operand and assign the value to identifier.

General form

Expression 1 +=expression2.

This is equal to expression 1 = expression +expression. Similarly there are four


other operators,
-=, *=, /= and %=.

+= add and store


-= subtract and store
*= multiply and store
/= divide and store

1. Relational Operators: These are used to evaluate the relation between the
operands such as less than, greater than etc. The output of these operations
is binary value. These operators are used to compare any two operands.
There are four relational operators. They are
a) < less than
b) <= less than or equal
c) > greater than
d) >= greater than or equal

There are two other operators which are closely related to them. They are
called equality operators.

a) == equal to
b) != not equal to

By the help of these operators we can form expressions known as logical


expression. The output of these expressions is either 1 (true) or 0(false).

Logical Operators: These are used to perform logical operations such as AND, OR
etc. Logical operators act upon operands which are themselves logical expressions.
These are used to combine individual logical expressions into more complex
expressions.

a) && and operation


b) || or operation
c) | no operation
Logical and operation will be true if both operands are true, logical or
operation
is true if any one of the expression is true.

1. Bit wise Operators: These operators are used to perform nit wise operations.

& AND
^ XOR
| OR
<< left shift
>> right shift

2. Unary Operators:

These operators act upon only one operand to produce a new value.

Unary Minus: All numeric constants are assumed to be positive. A negative


number is actually an expression consisting of unary minus and positive
constant.
Ex: -743, -root1, -0.2, -3*(x+y) etc.

Increment operator (++): The increment operator causes its operand to be


increased by one. It is represented by ++. If the operator is written before
operand, then the value of operand will be altered before it is utilized. If the
operator is written after the operand, the value of the operand will be altered
after it has been utilized.

Ex: ++|, |++, ++j, j++ etc.

Decrement operator (--): The decrement operator causes its operand to be


decreased by one. It is represented by --. If the operator is written before operand,
then the value of operand will be altered before it is utilized. If the operator is
written after the operand, the value of the operand will be altered after it has been
utilized.

Sizeof: This operator returns the size of its operand in bytes. The operand may be
an expression or may be a cast. This operator allows to determine the number of
bytes allocated to various data items.

Ex: Size of 1, size of (integer) etc.

– negation
! complement
& address operator
* Pointer
++ increment
-- decrement
Sizeof size of data

OPERATOR PRECEDNECE AND ASSOCIATIVITY


Precedence of an operator indicates the order of evaluation. Operators in C
are grouped together if they have same precedence. Again these groups are
arranged in hierarchical manner according to their precedence. Operations with
higher precedence are carried out before operations of lower precedence. The
operators with in a group have same precedence and are evaluated according to
their associativity.

Operator Associativity

:: L -> R

->. () postfix ++,-- L -> R

Prefix++, --, ~, !
Unary +, -, & (type) size of
new delete R -> L

->*,* L -> R

*,/,% L -> R

+, - L -> R

<<, >> L -> R

<, <=,>,>= L -> R

==, != L -> R

&, ^,| L -> R

&&, || L -> R

?: L -> R

= *=, /=,%=
+=, -= R -> L

1.9 Casting

Casting means specifying type of a variable. There are two types of casting
they are implicit casting and explicit casting. In implicit casting, the type of the
variable is automatically known by the compiler. Where as in explicit casting type is
defined by the programmer.

Whenever data types are mixed, conversion is automatically takes places to


wide data type. This process is known as implicit casting. Whenever a smaller type
operand and wider type operand is used in an expression, automatically smaller
type operand is converted to wider type. This is called widening conversion. If an
integer is used with a float, then integer is converted to float.

For explicit conversion we must use the type cast operator. There are two
versions for type casting

(type name) expression Or type name (expression)

Ex: int n, float total; float sum = total/float (n);

To make C++ programs more portable there are number of new casting
operators such as static.cast, dynamic.cast, const.cast and reinterpret.cast.

Static Casting:

Static casting is used when conversion between two related types arises.

Static.cast (<desired type> <expression>);

Conversion between numeric type, pointers etc are some of the examples of this.

Ex: int n; float d; int n= static.cast<int>(d);

1.10 Preprocessor

Q. What is preprocessor and what are its uses?

A preprocessor is a program used to modify the source program according to


directives supplied by the program. It is used to include library files, define macros,
assigning line numbers for compiler messages etc. It makes the source program
portable form one platform to other.

Some of the preprocessor directives are

#define define preprocessor macro

#error terminate processing early

#include insert text from another file

#if #else conditionally include text, based on expression

#elif combination of if and else

#endif terminate conditional text

#ifdef conditionally includes text based on predefined macro

#ifndef conditionally includes text with the sense of the text


#undef remove macro definitions

#line give line numbers to compiler messages.

1.11 Functions

Q. What is a function and what are the advantages of using functions in a program?

A function is self contained program segment that carries out some specific
well defined task. A function will carry out its intended actions whenever it is
accessed. Once the function has carried out its intended action, control will be
returned to the point from which the function was accessed.

Every program in C++ has a main function, which indicates the starting point
of its execution. If large programs are written within the main function, it will
become too complicated for debugging, testing etc. Thus a program must be
divided into different functional parts, which are executed independently. These sub
programs are called functions. This approach is known as modular programming.

Advantages of Modular Programming:

1. Top down designing can be implemented so that a high level logic is solved
by using low level functions.

2. Length of the source program can be reduced.

3. It is very easy to find errors and isolate faulty functions.

4. Same function may be used in many programs.

Q. What are different types of functions supported by C++ language?

C++ functions can be classified into two categories. They are (1) Library
functions and (2) User defined functions.

LIBRARY FUNCTIONS

A library function is a predefined function which carries out specific


operations on data Items. Functionally similar library functions are grouped together
in separate files. These files are available with C++ compiler. A library function is
accessed by writing the function name, followed by list of arguments.

Ex: Cout and Cin etc.

USER DEFINED FUNCTIONS


Same as that of library functions, user can create his own functions used to
perform specific tasks. A function will carry out its intended actions whenever it is
accessed. Once the function has carried out its intended action, control will be
passed to the function via special identifiers called arguments and returned via
return statement.

Depending on whether the arguments are present or not and whether a value
is returned or not, they are classified into

1. Functions with no arguments and no return values: When a function has no


arguments, it does not receive any data from the calling function and also it
does not return any value to calling function. Thus no data transfer is
performed between the calling function and called function.

2. Functions with arguments but no return values: Data can be passed to


function in the form of arguments by calling function. In called function
dummy arguments are used to define the operation to be performed, where
as calling function will send real arguments to called function when it is
accessed.

3. Functions with arguments and also with return values: The calling function
receives the data from called function through return statement.

A function is also similar to a procedure but it differs in certain aspects


such as if a function does not return any value to the function call then it is known
as void function or a procedure. A procedure can be called by using its name, but a
function can be called only in the assignment statement or expression used in Cout
or control statements.

STRUCTURE OF C++ FUNCTION

Q. Explain how a user defined function can be defined and used in a program?

General Format

Type function name (type arg1, type arg2,…)

1. First statement in function declaration, defines name of the function and list
of arguments. This statement must not terminated by;

2. A function can be accessed by calling its name, followed by a list of real


arguments.
3. The type of value returned by the function is given as type function. By
default it is taken as integer type. The type of expression used in return
statement must match with type of function.

4. A return statement returns a value to a calling function. If function does not


return any value, it must be declared as void type.

5. If there are no arguments, the function must be declared as void type.

6. Each function declaration must end with

7. Arguments may be scalars or arrays but the type must be specified.

8. The actual arguments in calling function must agree in number and order and
type with formal arguments.

9. Variables used in a function are local to that function but not known outside
the function.

10. A function may be kept in library so that many users can access it.

11.A function may be called by itself any number of times.

12.Function prototype must be defined in main program.

13.A function may be called by using its name and list of actual arguments.

Q. Explain how arrays are passed into functions or what is the difference between
call by value and call by reference?

When a function is defined its arguments are dummy parameters and when it
is called by calling function it sends real arguments to the called function. This type
of passing real parameters into a function is known as call by value.

Arrays also can be used as arguments in functions. When argument is an


array a copy of array elements is not sent to formal array, but the address where
the array is stored is made known to the calling function i.e., actual array and
formal array occupy same locations in memory. Even name of actual array is
different from formal array, they can have same location. This type of passing an
array address into a function is know as call by reference.

Also a function can return a reference. In this case the function type must be
specified as reference type i.e it must be preceded by int &.

Ex: int & max(int &x, int &y)


{
…………
}
Q, Write notes on default arguments and constant arguments?

Default Arguments:

In C++, a function may be called without arguments or without specifying all


its arguments. In such cases the function assigns a default value to the parameter
which does not have a matching argument in the function call. Default values are
specified when the function is declared.

Default values must be specified same as that of variable initialization. A


default argument is checked for type at the time of declaration and evaluated at the
time of call. We must add default arguments from right to left. It is not possible to
provide a default value in the middle of an argument list. Default arguments are
useful in situation where some arguments always have the same value.

Ex: void sum (int x=10, int y=20);


Main() void sum(int x, int y)
{ {
int a,b; int temp = s+y;
sum(); }

……

Constant Arguments:

In C++ an argument to a function can be declared as constant by using a


qualifier const. the qualifier const informs the compiler that the function should not
modify the argument. This type of declaration is significant only when we pass
arguments by reference or pointer.
Unit 1

C++ class overview – class definition, objects, class members, access control,
scope, constructors and destructors, parameter passing methods, inline functions,
static class members, this pointer, friend functions, dynamic memory allocation and
de-allocation, exception handling.

2.1 Types of programming


Roughly speaking, we can classify programming techniques into four categories,
• Unstructured programming,
• procedural programming,
• modular programming and
• object-oriented programming.

Unstructured Programming
Usually, people start learning programming by writing small and simple programs
consisting only of one main program. Here ``main program'' stands for a sequence
of commands or statements which modify data which is global throughout the
whole program. We can illustrate this as shown in Figure

This programming techniques provide tremendous disadvantages once the program gets
sufficiently large. For example, if the same statement sequence is needed at different locations
within the program, the sequence must be copied. This has lead to the idea to extract these
sequences, name them and offering a technique to call and return from these procedures.
Disadvantages:
○ program gets quickly too larges
○ no code reusability ( if the same statement sequence is needed at different
locations within the program, the sequence must be copied)
Procedural Programming
A program can be viewed as a sequence of procedure calls. With procedural
programming you are able to combine returning sequences of statements
into one single place. A procedure call is used to invoke the procedure. After
the sequence is processed, flow of control proceeds right after the position where
the call was made .
.

With introducing parameters as well as procedures of procedures ( subprocedures) programs can


now be written more structured and error free. For example, if a procedure is correct, every time
it is used it produces correct results. Consequently, in cases of errors you can narrow your search
to those places which are not proven to be correct.
The main program is responsible to pass data to the individual calls, the data is processed by the
procedures and, once the program has finished, the resulting data is presented. Thus, the flow of
data can be illustrated as a hierarchical graph, a tree, as shown in for a program with no sub
procedures.
The main program coordinates calls to procedures and hands over appropriate
data as parameters.

A single program is divided into small pieces called procedures. To enable usage of general
procedures or groups of procedures also in other programs, they must be separately available.
For that reason, modular programming allows grouping of procedures into modules.
Advantages:
○ some code reusability (within a program)
○ concept of parameter passing to procedures/functions.
Disadvantages:
○ how can other programs share the same procedures?
○ high dependence of code on procedures.

Modular Programming
With modular programming procedures of a common functionality are grouped
together into separate modules. A program therefore no longer consists of only one
single part. It is now divided into several smaller parts which interact through
procedure calls and which form the whole program.

The main program coordinates calls to procedures in separate modules and hands
over appropriate data as parameters.

Each module can have its own data. This allows each module to manage an internal state which
is modified by calls to procedures of this module. However, there is only one state per module
and each module exists at most once in the whole program.
Advantages:
○ more code reusability (within and amongst programs)
○ Each module can have its own data.
○ This allows each module to manage an internal state which is modified by calls to
procedures of this module.

Disadvantages:
○ There is only one state per module
○ Each module exists at most once in the whole program
○ Data and Operations always decoupled.... modules about grouping of operations.
Object-Oriented Programming

2.2 Object oriented programming/Procedure oriented programming

Q. Give an account of differences between object oriented programming and


procedure oriented programming?

Object oriented programming:

1. It employs bottom up approach to solve a given problem.


2. Emphasis is made on data rather than procedure
3. It mainly concentrates on implementation rather than process.
4. It will help to solve the problem in terms of application domain.
5. OOPs allows to decompose a problem into a number of entities called objects
then builds the data functions around these objects.
6. Programs are designed around the data being operated rather than the
operations themselves.
7. Oops provide security by data hiding and data abstraction.
8. Oops extends the meaning of normally used operations by defining them for
user defined functions through function overloading.
9. Oops supports dynamic initialization.
10.Oops supports polymorphism, encapsulation and inheritance properties.
11.It is used to solve a problem which can be divided into a number of modules.

Procedure oriented programming:

1. It employs top down approach to solve the problem.


2. Emphasis is made on procedure rather than data.
3. Most of the programs share global data.
4. Programs are organized in the form of subroutines and the data items are
freely accessible.
5. Data in procedure oriented language is open and can be accessed by any
function.
6. It won’t support dynamic initialization, function overloading, overriding etc.
7. It won’t support polymorphism, encapsulation and inheritance.
8. Data abstraction and data hiding is not possible.
9. It is used to solve a problem which cannot be divided into a number of
modules.

2.3 Goals of Object Oriented Programming


The major design goals of object oriented programming are
a) Robustness
b) Adaptability
c) Reusability

Robustness:
It is the capability of handling unexpected inputs that are not explicitly defined for
its application. A program must produce the right output for all anticipated inputs.

Ex: If user wishes to store more elements in a data structure than that of defined,
then the software should expand its capacity automatically.

Adaptability:

Reusability:

2.4 Characteristics of Object Oriented Approach

There are four characteristics of object oriented approach. They are

1. Identity: Data must be divided into discrete, distinguishable entities called


objects. Objects may be concrete or conceptual. Each object has its own
identity. In programs objects has a unique handle. The handle may be
address or index.

2. Emphasis on Object: Object Oriented technology focuses on object


structure but not on procedure structure. Emphasis is made on what an
object must be but not how it is used.

3. Classification: Objects with same data structure and behavior are grouped
into a class. A class is an abstraction of important properties of an
application. Each object is an instance of class. An object contains an implicit
reference to its own class.

4. Combining data behavior: By combining data and behavior, the decision


which procedure to be used is made implicit by each object. Polymorphism
enables to decide the implementation of a given operation according to data
supplied by caller.

5. Polymorphism: Same operation may be done differently on different


classes. An operation is an action or transformation that an object performs.
A specific implementation of an operation by a class is called a method.

6. Inheritance: Common structure and data can be shared among several


similar subclasses to eliminate redundancy .Sharing of attributes and
operations among classes based on hierarchical relations are called
inheritance. A subclass inherits all the properties of its super class and adds
its own properties.

7. Abstraction: It focuses on essential, inherent aspects of an entity. It deals


with application domain concepts but not design and implementation
decisions.

8. Encapsulation: It prevents massive effects when small changes occurs in


program. It separates external aspects of an object which are accessible to
other objects, from the internal implementation details of the object, which
are hidden.

2.5 Class

Q. Define class and how it is different from structure?

In C, we have structures which contain one or more data items called


members grouped together. It is a way of grouping logically related different types
of data items. Once the structure is defined, variables of structure type are
declared.

The major disadvantages in structures are

1. It won’t support data hiding.


2. It does not contain methods to access the members of structure.
3. By default members of the structure are public, thus structure members can
be accessed from any function in the program.

In C++, structures are modified as classes. A class is an abstract data type like
structure having all properties of structure. A class is an encapsulation of data and
its associated functions together. It supports data abstraction. By default the
members of the class are private. Thus the members of the class cannot be
accessed by the external functions.

Q. Explain how a class is defined?

A class has two parts. One is class definition and the other is class
declaration.

Class declaration:

A class declaration describes the type and scope of it members. A class


declaration is similar to structure declaration. A class declaration has three parts,
they are private, public and protected. Again these three sections may have
variables and functions. The members that are declared under private can be
accessed only within the class. Where as public members can be accessed from
outside the class also. Protected members are only accessible to derived classes
only.
General format of class:

Class name of the class


{
Public:
variables;
functions;
private:
variables;
functions;
protected:
variables;
functions;
};

The variables declared in a class are known as data members and functions
are known as member functions. Binding of data and functions together into a
single class is known as encapsulation.

Public members:
All data members and function are declared in the public section of the class
and can be accessed any where in the program either by functions of the class or by
the external to the class.

Ex: class complex


{
public:
int real;
int img;

};
complex x;
x.real;
x.img;

Private members:

By default members of the class are private. Private members can be


accessible by only member functions of the class. They cannot be accessible by the
functions outside the class.

Ex: class complex


{
Private:
int real;
int img;

Public;
get();
};
complex x;
x.get();

Protected members:

Protected members access control is similar to that of private members.

Q. Explain how member functions are defined in a class?

Member functions of a class can be defined in two ways – outside the class
definition and inside the class definition.

Outside the class:

Member functions that are declared inside a class have to be defined outside
the class. A member function must have identity to specify to which class it belongs
to. This can be achieved by scope resolution operator.

General form

Type class name :: function name (arguments)


{
………
}

Several classes can use the same function name but the member ship label
will resolve the scope of function. Member functions can access the private data of
the class. A member function can call another member function.

Ex: class complex


{
Private:
int real;
int img;
Public:

get();
};

void complex::get()
{

Cin>>real,img;
}
Inside the class;

We can replace the function declaration by the actual function


definition inside the class. When a function is defined inside a class it is treated as
inline function.

Ex: class complex


{
int real;
int img;
public:
void get()
{
cin>>real,img;
};

2.6 Object

Q. What is an object and how objects are created?

An object is a class variable. The instance of a class is known as object. The


generalization of similar properties of different objects is known as class. A class is a
data form. Where as an object is data type. Once the class is defined memory is not
assigned for the class. But when an object is created, memory is allocated for it.

An object can be created when a class is defined by placing their names


Immediately after the closing brace or we can create variables of that type by using
the class name.
Ex: Class complex
{
……….
} x,y;

Q. Define and distinguish object and class?

Object: It is defined as a concept or abstraction or a thing with boundaries and


meaning for the problem at hand. Objects serve two purposes, one is to
understand the real world and to implement on computer and the other is to
decompose problem into objects.

Class: It is a group of objects with similar properties and common behavior,


relationships with other objects. By grouping into classes, we abstract the problem
to a more generalized form. Common definitions are stored once per a class but
not per an instance.

An object can be treated as an instance of class, where as generalization of


similar type of objects is called class. Classes are user defined data types. It is a
data form like a structure. An object is a type variable of class. It is a run time
entity. Memory is allocated when ever an object is created.

Q. What is this pointer and how it is useful ?

‘This’ is a pointer that points to the object for which this function was called.
This unique pointer is automatically passed to a member function when it is called.
The pointer this acts as an implicit argument to all the member functions.
Ex: class xyz
{
int x;

};
We can access private variable x directly by the help of this pointer

this -> x=35;


We can also use this operator to pass one argument implicitly by using this pointer.
It also used to return the object it points to.

2.7 Inline Functions

Q. Write notes on inline functions?

An inline function is similar to macro in C language. Macros are mainly used


to avoid the overhead occurring in functions. When a function is called, cpu will
transfers execution from calling program to called program. Before transferring
execution, it pushes the status of calling program into stack and after returning
from the called program they are popped from the stack. Entire this process
requires a lot of time and also this overhead increases with number of functions and
number of function calls. To over come this problem macros are developed. But the
draw back in macros is that they are not checked during compilation.

To avoid this problem, C++ provides inline functions. A function that is


expanded in line when it is invoked is known as inline function. When ever an inline
function is invoked, it replaces the function call with corresponding function code.
The inline functions are defined as

Inline function name


{
……..
}

Ex: inline square(int a)


{
return(a*a);
}
Advantages:

1. The size of the object code is considerably reduced.

2. The inline function make a program run fast that is it increases the execution
speed.
3. Inline member functions are compact function calls.

Disadvantages:

1. Inline functions cannot be used in recursion.

2. If functions contain static variables, inline functions are not useful.

3. It takes more memory, because the statements that define the inline function
are reproduced at each point where the function is called.

Q. Explain how a function outside the class can be made inline?

We can define a member function outside the class definition. In the same
way we can also define a function as inline which is present outside the class. This
can be achieved by a qualifier inline.

Ex: Class complex


{
int a,b;
public:
Void get();
};
inline void complex::get()
{
cin>>a,b;
}

Q. Write notes on static members and static member functions?

A static member is initialized to zero when the first object of its class is
created. It is visible within the class. Only one copy is created for the entire class
and shared by all the objects of class. The static data members must be created
and initialized before the main. Static variables are used to maintain values
common to the entire class. The type and scope of static members must be defined
outside the class definition. Static data members are stored separately but not as a
part of object. Hence these are called as class variables. A data member of a class
can be qualified as static.
Ex: class S
{
static int x;
public:
display();
};
int S::x=0;

A static member function can have access to only other static members of
same class. A static member can be called using the class name. The static member
function acts as global for member of its class without affecting the rest of the
program. A static member function cannot be virtual function.

2.8 Friend Functions

Q. What is friend function and explain how it is useful?

If there is any association between two or more classes, we can realize the
association by the help of friend function. If two or more classes has a common
function, then it can be written outside a class and made friend to all respective
classes. A friend function can access the private data of classes to which it behaves
as friend.

General format to make a function as friend

Class empl
{
……
Public:
Friend tax(empl x);
};

tax()
{
return (x.basic*.1);

}
A friend function is not a member of class, but it can access all private
members of class. It is not in the scope of the class and hence it cannot be called
buy using the object of the class. It can be declared either in public or in private
part of a class. It cannot access directly member names and has to use an object
name and dot membership operator. When all the members of one class are friend
functions of other class, the it is called friend class.
2.9 CONSTRUCTIONS & DESTRUCTORS

Q. What is a constructor and in how many ways a constructor can be defined?

Constructor is mainly used for initialization of an object automatically when it


is created. It is a member function used to initialize the objects of a class. It is called
a constructor because it constructs the value of data members of the class.

1. A constructor should have same name as that of class.


2. A constructor is automatically invoked whenever the object is created.
3. A constructor should be declared in the public section only.
4. They do not have return type.
5. They cannot be inherited.
6. They can have default arguments.

Ex: Class complex


{
int real;
int img;
public:
complex();
……..
}
complex::complex()
{
real=0;
img=o;
}

A constructor that does not accept any parameters is known as default


constructor.

Parameterized constructors:

Constructors with arguments are called parameterized constructors. We can


pass the arguments to constructor function when the objects are created.

Ex: Class complex


{
int real;
int img;
public:
complex(int x,y);

…..
}
complex::complex(int x,y)
{
real=x;
img=y;
}

Copy constructor:

A copy constructor is used to declare and initialize an object from another


object. They are used to create a temporary object of a class .

General form to create copy constructor

Class name :: class name(class name and pointer)

Ex: Class complex


{
int real;
int img;
public:
complex(const complex &a);
…..
}

complex::complex(const complex &a)


{
real =a.real;
img=a.img;
}

Complex c1; default constructor


Complex c2(3,4); parameterized constructor
Complex c3(c1); copy constructor

Constructor with default arguments:

We can define a constructor with default arguments. Even when the


argument
is not specified, the default value of the argument will be taken.

Ex: Class complex


{
int real;
int img;
public:
complex(int x,y=0);
…..
}
complex::complex(int x)
{
real=x;
img=y;
}

Multiple constructors:

We can use any number of constructors in a class. We can use a constructor


with arguments and another with out arguments in the same class.

Dynamic constructor:

Constructors can be used for allocating memory automatically when the


objects are created. Such constructors are called dynamic constructors. Allocation
of memory to objects at the time of their construction is known as dynamic
construction of objects.

Q. What is a destructor and what is its use?

A destructor is member function that automatically executes when an object


is destroyed. It is mainly used for resource management such as release of space
on the heap.

1. A destructor function also has name as that of class.


2. It must declared in the public section.
3. It does not have any arguments.
4. It does not have any return type.

Ex: Class complex


{
int real;
int img;
public:
complex(int x,y);
~complex();
}

The purpose of a destructor is to perform any housekeeping task that may be


necessary before a value is discarded.
Common house keeping tasks are:
1. Avoiding memory leak.
2. Closing files.
3. Releasing other system resources.

If no destructor is provided, default destructor will be automatically generated.

Q. Write notes on (a) Scope resolution operator (b) Manipulators (d) Deference
Operator

Scope resolution operator:


The scope of a variable is limited to the block where it is declared. A block is
the group of statements enclosed in curly braces {..}. A variable initializes when we
enter a function/block and it dies when we return from the function/block. These
variables are local to that function. Global version of the variable cannot be
accessed from inner block. This can be achieved by scope resolution operator.

General form

:: variable name

Ex: int x=10


main()
{
int x=5;

cout << x;
cout <<::x:

Output: 10 and 5

Manipulators:

These are used to format the data that is to be displayed. The most
commonly used manipulators are endl and setw.

Endl:

It is used for linefeed. It is equal to new line character \n.

Ex: cout << x << endl;


Cout<< y << endl;

Setw:

It is used to the field width of the data that is to be displayed.

Ex: cout<<setw(5) <<total << endl;

Dereference Operators:

These operators are used for accessing class members. There are three
pointer to member operators.

1. To declare a pointer to a member of a class


2. To access a member using object name and a pointer to that
member

3. To access a member using pointer to the object and a pointer to


that
member.

Q. Write notes on dynamic memory management and give examples for allocation
and de allocation of memory?

If the memory is allocated during compile time, then it is known as static


memory management. If the memory is allocated during run time then it is known
as dynamic memory management. Dynamic memory management enables the user
to allocate memory to the objects when ever it is required. This will save a lot of
wastage of memory.

The memory in C++ programs is divided into four categories:

1. Code Memory: The area contains machine instructions for all functions and
member functions.

2. Static data Memory: This area contains all global variables, as well as any
local variables or class members that are declared using the static modifier.

3. Run time stack: All local, non static variables reside on the run time stack.

4. Free store or Heap: This is the area for memory explicitly requested using the
new operator.

Memory Management Operators:

These are used for dynamic memory management. They are new and delete.
New is same that of malloc in c and delete is same as that of free in C. These are
also known as free store operators.

General format of new

Pointer variable = new data type;


Or Pointer variable = new data type;(initial value);
Or Pointer variable = new data type;[size];

Ex: P = new int;


Q = new float;

Int *P = new int (25);


Int *P = new int[10];
General format of delete

Delete pointer variable;


Or Delete [size] pointer variable;

Ex: delete p;
delete[ ]p;

Q. Write notes on pointer to objects ?

A pointer can also be used to point to an object created by a class. Object


pointers are useful in creating objects at run time. We can also use an object
pointer to access the public members of an object.

Ex: class book


{
int code;
float price;
public;
void getdata (int a, float b)
{ code =a;
Price = b;
}
void show(void)
{
cout <<code<<price;
}
};
main()
{
book x;
book *p=&x;
….
}

Now the pointer p is the pointer to object x. We can refer to the member
functions of book by using either dot operator or by using pointer.

x. getdata (10, 10, 50);


x. show ();

or
p->getdata (10, 10, 50);
p->show ();

We can also create the objects using pointers and new operator as given
below.

book *p= new book;

We can use the pointers not only to base objects but also to the objects of
derived classes. A single pointer variable can be made to point to object belonging
to different classes.

If class A is the base class and class B is the derived class and p is a pointer
to base class. Then

Class A
{
….
}

A a;
A*p=&a;
Class B; public A
{

}

B b;
The we can make the same pointer to the derived object B also
P = &b;

But by the help of such a pointer we can only access the members which are
inherited from A and not the original members of the B.

Q. What is meant by memory leak?

If the address assigned to a pointer is changed without deleting the object to which
it is pointing, there is no way to access this pointer. Therefore the memory assigned
to this object can never be used in future. Having such inaccessible objects in
dynamic memory is called memory leak.

Q. What is a name space? How it can be useful?


A name space is a mechanism that allows a group of related names to be defined in
one place. It is used to organize the global objects into natural groups and
minimizes the problem of security with global variables.

Namespaces generally contain definitions of more complex objects, including


types, classes and functions. An object X in the namespace can be accessed using
the notation

Group:: X which is called its fully qualified name.

Ex: namespace globals


{
int rows = 3;
int cols = 3;
}

Globals::rows, refers to the copy of variable in namespace.

If we are repeatedly using variables from the same namespace, it is possible to


avoid entering namespace by telling lthe system that we want to “use” a particular
specifier.

Using namespace globals.

Q. Give the significance of exception handling and explain how it can be used to catch the
errors in the program?
Programs:

1. Simple CLASS program.

#include <iostream.h>
#include <iomanip.h>
#include <string.h>

class book
{
public: char title[256];
char author[64];
float price;
void show_title(void)
{
cout << title << '\n';

}
void show_author()
{
cout << author<< '\n';

float get_price()
{
return(price);
}
};

void main(void)
{
book Ds;

strcpy(Ds.title, "Programming in C++");


strcpy(Ds.author, "E.S.Reddy");
Ds.price = 399.00;

Ds.show_title();
Ds.show_author();
cout << "The book's price is " << setprecision(2) <<
Ds.get_price();
}
1. Simple CLASS program with scope resolution operator

// Class when function's body is defined outside of the class

#include <iostream.h>
#include <iomanip.h>
#include <string.h>

class book
{
public: char title[256];
char author[64];
float price;

// Prototypes of member functions

void show_title(void);
void show_author();
float get_price();
};

// Function's definitions

void book :: show_title(void)


{
cout <<"\n "<< title;

}
void book :: show_author()
{
cout <<"\n "<< author<< '\n';

float book :: get_price()


{
return(price);
}

// Funcion main

void main(void)
{
book Ds;

strcpy(Ds.title, "Programming in C++");


strcpy(Ds.author, "E.S.Reddy");
Ds.price = 399.00;
Ds.show_title();
Ds.show_author();
cout << "The book's price is " << setprecision(2) << Ds.get_price();
}

2. CLASS program with CONSTRUCTOR

// Constructor

# include<iostream.h>

class Count
{
private: int c;
public:
Count () // Constructor
{
c= 0;
cout<<"\n Constructor";
}
void Increment ()
{
c++;
}
int Input ()
{
return (c);
}
};

void main()
{
Count c1, c2;
cout<<"\n c1 = "<<c1.Input ();
cout<<"\n c2 = "<<c2.Input ();
c1.Increment ();
c1.Increment ();
c2.Increment ();
c2.Increment ();
c2.Increment ();
cout<<"\n c1 = "<<c1.Input ();
cout<<"\n c2 = "<<c2.Input ();
}
4. // DESTR.CPP
// Destructor

# include<iostream.h>
# include<string.h>

class String
{
private: char *str;
public:
String (char *s) // Constructor
{
int length = strlen (s);
str = new char [length +1];
strcpy(str, s);
}

~String() // Destructor
{
cout<<"\n Destructor";
delete str;
}
void Output ()
{
cout<<"\n"<<str;
}

};

// Function main

void main ()
{
String S1 = "Expert Data Structures With C++";
cout<<"\n";
S1.Output ();
}

5. / new and delete operators

// NEWDEL.CPP

# include<iostream.h>

void main()
{
int *data;
int size;
cout<<"\n Input size of array: ";
cin >> size;
data = new int (size); // allocates an array of integers
for (int j = 0; j < size; j++)
{
data[j]= j;
cout<<data[j]<<"\t";;
}
cout<<"\n";
delete [] data; // Deallocate an array
// again allocating array but not assning data
cout<<"\n Without assigning second time data to \n";
cout<<"the array we are getting output apprimate same\n";
data = new int (size);
for (j = 0; j < size; j++)
cout<< data[j]<<"\t";
}
6. Member function when body of the function
// defined within the structure

#include <iostream.h>

struct Message
{
char *message;

// Member function

void show_message()
{
cout << message;
}
};

// Function main

void main(void)
{
Message Display;
Display.message = "C++ is a poweful language";
Display.show_message();
}
Unit II
Function overloading, Operator overloading, Generic programming-function and
class templates, inheritance basics, base and derived classes, inheritance types,
base class access control, runtime polymorphism using virtual functions, abstract
classes, stream I/O.

OVERLOADING

Q. What is meant by operator overloading and explain how it is used?

Overloading is an example for polymorphism. Poly means many and


morphism means actions. If same operation is performed differently on different
data types then t is known as polymorphism. Using same operator for different
operations is known as over loading. Operators have different meaning for a given
data type. By the help of over loading we can change the semantics of an operator
but not the syntax.

1. Except class member, scope resolution, size of, conditional operators


preprocessor symbols all other operators can be over loaded.

2. Only those operators that are predefined in C++ compiler can be over
loaded.

3. User cannot change the operator template.

4. Overloading never gives meaning which is radically different from its natural
meaning.

5. Overloaded operator must have at least one operand of user defined.

Overloading is done with the help of a special function called operator


function. The general form of operator function is

Type class name :: operator op(arguments)


{
……
}
To overload an operator follow the below steps

1. Create a class that defines the data type that is to be used in overloading.
2. Declare the operator function operator op() in public section.
3. Define operator function or a friend function.

Ex: Overloading Binary operator:

Class complex
{
int real;
int img;
public:
complex(){}

complex(int x,y)
{
real=x, img=y;
}
complex operator+(complex x,y);
void show();
};
complex complex::operator+(complex x,y)
{
complex t;
t.real=x.real+y.real;
t.img=x.img+y.img;
return(t);
}
void complex::show(void)
{
cout<<real,img;
}
main()
{
complex a,b,c;
a=complex(1,2);
b=complex(3,4);
c=a+b;
cout<<c.show;
}

Q. Explain how input/output operators can be overloaded?

In C++ we have>> and << operators used for input and output the data.
These operators can work with all types of data such as int, long, float etc. Thus
they are already overloaded in C++ complier.
To implement input operator >> below function is used.

Istream & operator >>(istream &,is,strin &s)


{
const bufsize=100;
char buf[bufsize];
if(is.get(buf,bufsize))s=string(buf);
return is;
}

To overload the output operator << we need a public member function for the class
that can handle the output.

Void string::print(ostream&os)const
{
s.print(os)
return os;
}

Q. Write notes on function overloading?

If the same function is used for different operations then it is said to be


polymorphism. It is a logical way of using same function with different arguments to
perform different operations. Even though the method is same mechanism changes.
Thus there may occur many functions with same name. when a function is called
the correct function is invoked by checking the number and type of arguments.

A function cal first matches the prototype having the same number and type
of arguments and then calls the appropriate function for execution. If an exact
match is not found, complier uses the integral promotions, built in conversions and
user defined conversions and their combinations.

Advantages:

1. Eliminates the use of different function names for the same operation.
2. Function over loading has easy maintainability of the code.
3. Better understanding of the relation between the program and the outside
world.
4. Debugging is easy.

Ex: int area(int);


int area(int,int);

Main()
{
cout<<area(10);
cout<<area(2,5);
}

int area (int r)


{
return(3.14*r*r);
}

int area(int a,b)


{
return(a*b);
}

Q. Explain how strings are manipulated using operators?

There are no operators in C to manipulate strings. But in C++ it is possible by


the help of over loading. We can define our own definitions for operators to
manipulate the strings. For example concatenation of strings is performed by using
library function strcat(). Where as the same operation can be achieved by
overloading the + operator as shown below.

Ex: const int size =10;


Class string
{
char st[size];
public:
string()
{
strcpy(str,”);
}
string(char *str-a)
{
strcpy(str,str-a);
}
void out()
{
cout<<str;
}
string operator+(string s)
{
string temp = str;
strcat (temp.str,s.str);
return temp;
}
};
main()
{
string str1=”welcome”;
string str2=”friend”;
string str3;
sr1.out;
str2.out;
str3=str1+str2;
str3.out();}

INHERITANCE

Q. What is meat by inheritance and how many types of inheritances are there?

Sharing of attributes and operations among classes bases on hierarchical


relations is called inheritance. The process of creating a new class form an existing
class is known as inheritance. A sub class inherits all the properties of its super
class and adds its own properties. It is a logical way of arranging the attributes in a
hierarchical manner to eliminate redundancy.

The class from which properties re derived is known as base class and the
class which derives the properties is known as derived class. Inheritance provides
the reusability of the code.

There are different types of inheritance. They are

1. Single inheritance: if a class derives the properties of one class then it is


called single inheritance.

2. Multiple inheritance: If a class derives the properties from two or more base
classes then it is called multiple inheritance.

3. Hierarchical inheritance: If the properties of one class is derived by more than


one derived class then it is known as hierarchical inheritance.

4. Multilevel inheritance: If a derived class derives the properties from other


derived class then it is called multilevel inheritance.

5. Hybrid inheritance: If more than one form of inheritance is involved then it is


called hybrid inheritance.

6. Multi path inheritance: If a class is derived from other derived classes which
are derived from the same base class is called multiple path inheritance.
Q. Explain how a derived class is declared and used?

A derived class extend its features by inheriting the properties of another


class and features of its own.

General to declare a derived class

Class derived class: (visibility mode) base class


{
…..
};

Where visibility mode is the inheritance type of public or private. The default
visibility is private. When a base class is privately inherited by a derived class,
public members of the base class become private members of the derived class.
The private members are not inherited and they will never become the member of
its derived class.

When base class is privately inherited by a derived class, public member of


the base class become private members of the derived class.

When the base class is publicly inherited, public members of the base class
becomes public members of derived class.

When the base class is inherited by default the public members of the base class
becomes the private members of the derived class.

Q. Write notes on different types of access control of a base class?

There are three types access controls of a base class namely public private
and protected.

1. Public Access Control;

Here derived class can a access the public and protected members of the base
class, but not private members of the base class. By using publicly derived class
the public members of the base class becomes the protected members of the
derived class.

Ex: class B
{
int x;
f1();
public:
int y;
f2();
protected:
int z;
f3();
};
class A:public B
{
int p;
f4();
public:
int q;
f5();
protected:
int r;
f6();
}

Therefore the attributes y,q and member functions f2,f5 will become
public and the attributes z,r and functions f3,f6 become private in derived class.

2. Private Access Control:

Here the derived class can access the public and private members of the
base class privately. The public and protected members of the base class becomes
private members of the derived class.

Ex : class B
{
int x;
f1();
public;
int y;
f2();
protected;
int z;
f3();
};

Class A: private B
{
int p;
f4();
public;
int q;
f5();
protected;
int r;
f6();
};
Therefore the attribute q and member function f5 will become public and the
attributes p, z, y and functions f4, f2, f3 become private in derived class.

2. Protected Access Control :


The protected access control means that the derived class can access the
public and protected members of the base class protectedly. The public and
protected members of the base class become protected members of the derived
class.
Ex : class B
{
int x;
f1();
public;
int y;
f2();
protected;
int z;
f3();
};

Class A: protected B
{
int p;
f4();
public;
int q;
f5();
protected;
int r;
f6();
};
Therefore the attribute q and member function f5 will become public and the
attributes z, y, r and functions f6, f2, f3 become protected in derived class.

Q. Distinguish between multilevel inheritance and multiple inheritance ?

In multiple inheritance the derived class inherits the properties from two or
more base classes, where as in the case of multi level inheritance a derived class
inherits the properties from other derived class.

The general form for multiple inheritance is

Class derived class: (visibility mode) base class 1, class 2 …..


Ex : Class A: public B, public C
{
……
}
The general form for multi level inheritance is

Class derived class 1 : visibility base class

Class derived class 2 : visibility derived class 1

Ex : Class A : public B
Class C : public A
Q. Write notes on virtual base class ?

The duplication of inherited members due to multiple paths in inheritance can be


avoided by the help if virtual base class. When a class is made virtual only one
copy of that class is inherited. When a derived class inherits attributes from more
than one other derived classes then there may occur duplication of members. This
problem can avoided by using virtual base class.

Ex : class A
{
…..
};
Class B1: virtual public A
{
….
}

Class B2: public virtual A


{
….
}
Class C: public B1, public B2;
{
….
}

Q. Write notes on constructors in derived classes ?

If a base class constructor takes any arguments the derived class need not
have a constructor. If any base class contains a constructor with one ore more
arguments then it is compulsory for the derived class to have a constructor and
pass the arguments to the base class constructors. The base classes are
constructed in the order in which they appear in the declaration of the derived
class. Similarly the constructors are executed in the order of inheritance.

The constructor of the derived receives the entire list of values as its
arguments and passes them on to the base constructors in the order in which they
are declared in the derived class. The base constructors are called and executed
before executing the statements in the statements in the body of the derived
constructor.

The general form of derived constructor

Derived constructor (arglist 1, arglist 2, …)

Base 1 (arglist1),
Base 2(arglist2),
….
{
function of derived constructor
}

Ex: If C is derived form A and B, then


C(int a, b, c);
A(a);
B(b);
{
x = c;
}

Q. Distinguish between early binding and static binding ?

The overloaded member functions are selected for invoking by matching


arguments, type and number. This information is known to the compiler at the
compile time. Thus the compiler is able to select the appropriate function for a
particular call. This is called early binding or static binding. By using static binding
we can achieve more efficiency and function calls are made faster.

Where as in dynamic binding the actual function called at runtime depends


on the contents of the function pointers. At runtime it is known that which class
objects are under construction, the appropriate version of the function is called.
The connection between the function call and the code executed by the call is
determined late. So it is also called late binding.
Q. What is a virtual function and explain how it is used ?

When the same function is used in both base and derived classes, the
function in base class is declared as virtual. The same pointer used to base class
can be used to refer to all derived objects. But even base pointer is made to
contain the address of derived class, it executes the function in the base class. The
compiler ignores the contents of the pointer and chooses the member function that
matches the type of the pointer. It is achieved through virtual function.

When we use the same function both in base and derived classes, the
function n base class is declared as virtual using the key word virtual. We must
access the virtual function through the use of a pointer declared as a pointer to the
base class.

General form for declaring virtual function


Class name
{
…..
Public;
Virtual type function name(arguments)
{
…..
}};
Ex: class poly
{
int a,b;
public;
virtual int mul();
virtual void output();
};

The following rules must be followed while using virtual functions.

1. Virtual functions are the members of the same class


2. They cannot be static members.
3. They are accessed by using object pointer.
4. The class cannot have virtual constructors but can contain virtual destructor.
5. A virtual function can be a friend of another class.
6. If a virtual function is defined in the base class it need not be in the derived
class.
7. They must be declared in public section.

Virtual functions with a null body are to do nothing i.e., it has no definition is
called pure virtual function. Pure virtual function is declared as a virtual function
with its declaration followed by zero or a pure virtual function is a type of function
which has only a function declaration but not have the function definition.

General form to declare pure virtual function is

Class name
{
public;
….
virtual type function name(arguments)=0;
….
};

Ex: class xyz


{
int a,b;
public;
virtual void input()=0;
virtual void output()=0;
};

A pure virtual function can be invoked by its derived class. A pure virtual
function is not implemented in base class. It has a null body and the derived class
is supposed to fill.

Q. What is a generic class? What is its significance? Explain with examples? Or what
are function templates?

Generic class : The class which allows to create a function template whose functionality can be
adapted to more than one type or class without repeating the entire code for each type.

Function templates are special functions that can operate with generic types.

In C++ this can be achieved using template parameters. A template parameter is a special kind of
parameter that can be used to pass a type as argument: just like regular function parameters can be
used to pass values to a function, template parameters allow to pass also types to a function. These
function templates can use these parameters as if they were any other regular type.
The format for declaring function templates with type parameters is:
template <class identifier> function_declaration;
template <typename identifier> function_declaration;
The only difference between both prototypes is the use of either the keyword class or the keyword
typename. Its use is indistinct, since both expressions have exactly the same meaning and behave
exactly the same way.
For example, to create a template function that returns the greater one of two objects we could use:

template <class myType>


myType GetMax (myType a, myType b) {
return (a>b?a:b);
}ere we have created a template function with myType as its template parameter. This template
parameter represents a type that has not yet been specified, but that can be used in the template
function as if it were a regular type. As you can see, the function template GetMax returns the greater
of two parameters of this still-undefined type.
To use this function template we use the following format for the function call:
function_name <type> (parameters);
For example, to call GetMax to compare two integer values of type int we can write:

int x,y;
GetMax <int> (x,y);
When the compiler encounters this call to a template function, it uses the template to automatically
generate a function replacing each appearance of myType by the type passed as the actual template
parameter (int in this case) and then calls it. This process is automatically performed by the compiler
and is invisible to the programmer.
Here is the entire example:
#include <iostream>
using namespace std;

template <class T>


T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}

int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax<int>(i,j);
n=GetMax<long>(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}

In this case, we have used T as the template parameter name instead of myType because it is shorter
and in fact is a very common template parameter name. But you can use any identifier you like.
In the example above we used the function template GetMax() twice. The first time with arguments
of type int and the second one with arguments of type long. The compiler has instantiated and then
called each time the appropriate version of the function.
As you can see, the type T is used within the GetMax() template function even to declare new
objects of that type:

T result;
Therefore, result will be an object of the same type as the parameters a and b when the function
template is instantiated with a specific type.
In this specific case where the generic type T is used as a parameter for GetMax the compiler can find
out automatically which data type has to instantiate without having to explicitly specify it within angle
brackets (like we have done before specifying <int> and <long>). So we could have written instead:
int i,j;
GetMax (i,j);
Since both i and j are of type int, and the compiler can automatically find out that the template
parameter can only be int. This implicit method produces exactly the same result:

#include <iostream>
using namespace std;

template <class T>


T GetMax (T a, T b) {
return (a>b?a:b);
}

int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax(i,j);
n=GetMax(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}
Notice how in this case, we called our function template GetMax() without explicitly specifying the
type between angle-brackets <>. The compiler automatically determines what type is needed on each
call.
Because our template function includes only one template parameter (class T) and the function
template itself accepts two parameters, both of this T type, we cannot call our function template with
two objects of different types as arguments:

int i;
long l;
k = GetMax (i,l);
This would not be correct, since our GetMax function template expects two arguments of the same
type, and in this call to it we use objects of two different types.
We can also define function templates that accept more than one type parameter, simply by specifying
more template parameters between the angle brackets. For example:

template <class T, class U>


T GetMin (T a, U b) {
return (a<b?a:b);
}In this case, our function template GetMin() accepts two parameters of different types and returns
an object of the same type as the first parameter (T) that is passed. For example, after that
declaration we could call GetMin() with:

int i,j;
long l;
i = GetMin<int,long> (j,l);or simply:
i = GetMin (j,l);
even though j and l have different types, since the compiler can determine the appropriate
instantiation anyway.

Class templates
We also have the possibility to write class templates, so that a class can have members that use
template parameters as types. For example:

template <class T>


class mypair {
T values [2];
public:
mypair (T first, T second)
{
values[0]=first; values[1]=second;
}
};
The class that we have just defined serves to store two elements of any valid type. For example, if we
wanted to declare an object of this class to store two integer values of type int with the values 115
and 36 we would write:
mypair<int> myobject (115, 36);
this same class would also be used to create an object to store any other type:
mypair<double> myfloats (3.0, 2.18);
The only member function in the previous class template has been defined inline within the class
declaration itself. In case that we define a function member outside the declaration of the class
template, we must always precede that definition with the template <...> prefix:

#include <iostream>
using namespace std;

template <class T>


class mypair {
T a, b;
public:
mypair (T first, T second)
{a=first; b=second;}
T getmax ();
};

template <class T>


T mypair<T>::getmax ()
{
T retval;
retval = a>b? a : b;
return retval;
}

int main () {
mypair <int> myobject (100, 75);
cout << myobject.getmax();
return 0;
}
Notice the syntax of the definition of member function getmax:
template <class T>
T mypair<T>::getmax ()
Confused by so many T's? There are three T's in this declaration: The first one is the template
parameter. The second T refers to the type returned by the function. And the third T (the one
between angle brackets) is also a requirement: It specifies that this function's template parameter is
also the class template parameter.

Template specialization
If we want to define a different implementation for a template when a specific type is passed as
template parameter, we can declare a specialization of that template.

For example, let's suppose that we have a very simple class called mycontainer that can store one
element of any type and that it has just one member function called increase, which increases its
value. But we find that when it stores an element of type char it would be more convenient to have a
completely different implementation with a function member uppercase, so we decide to declare a
class template specialization for that type:
// template specialization 8
#include <iostream> J
using namespace std;

// class template:
template <class T>
class mycontainer {
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
};

// class template specialization:


template <>
class mycontainer <char> {
char element;
public:
mycontainer (char arg)
{element=arg;}
char uppercase ()
{
if
((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};

int main () {
mycontainer<int> myint (7);
mycontainer<char> mychar ('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}
This is the syntax used in the class template specialization:
template <> class mycontainer <char> { ... };
First of all, notice that we precede the class template name with an emptytemplate<> parameter list.
This is to explicitly declare it as a template specialization.
But more important than this prefix, is the <char> specialization parameter after the class template
name. This specialization parameter itself identifies the type for which we are going to declare a
template class specialization (char). Notice the differences between the generic class template and
the specialization:
template <class T> class mycontainer { ... };
template <> class mycontainer <char> { ... };
The first line is the generic template, and the second one is the specialization.
When we declare specializations for a template class, we must also define all its members, even those
exactly equal to the generic template class, because there is no "inheritance" of members from the
generic template to the specialization.

Non-type parameters for templates


Besides the template arguments that are preceded by the class or typename keywords , which
represent types, templates can also have regular typed parameters, similar to those found in
functions. As an example, have a look at this class template that is used to contain sequences of
elements:

#include <iostream>
using namespace std;

template <class T, int N>


class mysequence {
T memblock [N];
public:
void setmember (int x, T value);
T getmember (int x);
};

template <class T, int N>


void mysequence<T,N>::setmember (int x, T value) {
memblock[x]=value;
}

template <class T, int N>


T mysequence<T,N>::getmember (int x) {
return memblock[x];
}

int main () {
mysequence <int,5> myints;
mysequence <double,5> myfloats;
myints.setmember (0,100);
myfloats.setmember (3,3.1416);
cout << myints.getmember(0) << '\n';
cout << myfloats.getmember(3) << '\n';
return 0;
}
It is also possible to set default values or types for class template parameters. For example, if the
previous class template definition had been:
template <class T=char, int N=10> class mysequence {..};
We could create objects using the default template parameters by declaring:
mysequence<> myseq;
Which would be equivalent to:
mysequence<char,10> myseq;

I/O STREAMS

Q. What is a stream and what are different stream classes supported by C++?

To interface different peripherals. C++ provides an I/O system known as


stream. A stream is a sequence of bytes. It acts as a source from which the input
data can be obtained or as a destination to which the output data can be sent. It
acts as an interface between IO devices and program.

C++ supports different stream classes to define various streams to deal with
both console and disk diles. Some of them are

Los Input/output stream class used by all input and output classes

Istream input stream declares get(), getline(), read(), >>

Ostream outputstream declares put(), write(), <<

Lostream input/output stream inherits the properties of I and


Ostreams

Cin and Cout:

Cin and cout are predefined objects in iostream.h file for input and output of
data of various types. This is possible by overloading >> and << operators.
General form

Cin>> variables;
Cout<< variables;
Ex: int a;
Cin>>a;
Cout<<a;

Put () and Get() functions:

Get() function is available in stream and put() function is available in


ostream. There are two types of get() function, they are get(char*) and get(void).

Ex: Char c;
Cin.get (c);

Or c=cin get();

Similarly put() function is used to output a line of text or character.


Ex: cout.put (c);

Getline() and Write() functions:

Getline function is used to read a whole line of text that end with a new line
character. General form of getline function is

Cin.getline (line, size);

Where line is the variable into which text is read until new line character
encounters or size -1.

Ex: Char name[10];


Cin.getline (name, 10);

Similarly to display entire line we can use write function. General form of
write function is

Cout.write(line, size);

Ex: cout.write(name,10);

Q. Write notes on different features used for formatting the output ?

There are three different features for formatting the output. They are
1. ios class functions and flags.
2. Manipulators
3. User defined output functions.

Los class functions :

Width() to specify the required field size for displaying an output value.

Precision() to specify the number of digits to be displayed after the decimal point.

Fill() to specify the character that is used to fill the unused portion of a field

Setf() to specify format flags that can control the form of output display.

Unsetf() to clear the flags specified.

Manipulators:

To access the manipulators the file iomanip.h must be included. They are
used for formatting parameters of a stream.

Setw() Same as width()

Setprecision() Precision()

Setfill() fill()

Setiosflags() setf()

Resetioslfags() unset()

Ex: cout width(w);


Cout precision(d);
Cout.fill(ch);

Cout<<setw(5)<<setprecision(2)<<1.25;

Formating flags:

To set the formatting flags we must use setf() function as shown below

Cout.setf(arg 1,ag2);
Where arg1 is formatting flag and arg2 is bit field specifying the group to
which the flag belongs to.
Flag bit field
For left justification ios::left ios::adjusted

Right justification ios::right ios::adjusted

Padding ios::internal ios::adjusted

Scientific notation ios::scientific ios::floatfield

Fixed point notation ios::fixed ios::floatfield

Decimal ios::dec ios::basefield

Octal ios::oct ios::basefield

Hexa ios::hex ios::basefiel

The below flags donot have bit fields

Display trailing zeros ios::show point

Print + before positive numbers ios::showpos

Show point and trailing zeros ios::showpoint

Skip whte space ios::skipus

Flush all streams ios::unitbuf

User defined Functions:

We can design our own manipulators as shown below.

Ostream & manipulator (ostream & output)


{
….
Return output;
}
UNIT III
Algortihms, performance analysis- time and space complexities. Review of basic
data structures- List , stack, queue and their implementation using template classes
in C++.

1. Algorithm

An algorithm is a step by step procedure to represent the solution for a given problem. It consists of a
sequence of steps representing a procedure defined in a simple language to solve the problem.It was first
proposed by a Persian mathematician, ABU JAFAR MOHAMMED IBN MUSA AL KHWARIZMI IN
825 A.D.
1.1 Characteristics of an Algorithm:
1. An algorithm must have finite number of steps.
2. An algorithm must be simple and must not be ambiguous.
3. It must have zero or more inputs
4. It must produce one or more outputs.
5. Each step must be clearly defined and must perform a specific function.
6. There must be relationship between every two steps.
7. It must terminate after a finite number of steps
Ex: Algorithm for Towers of HANOI
Problem: The objective of the game is to transfer n disks from leftmost pole to right most pole, without
ever placing a larger disk on top of a smaller disk. Only one disk must be moved at a time.
Algorithm TOH (n, x, y, z)
//Move n disks from tower x to tower y//
{ if (n>=1) then
{ TOH( n-1, x, z, y);

printf(“move top disk from”, x “to” y);

TOH( n-1, z, y, x);

1.2 How to develop an algorithm:


1. The problem for which an algorithm is being precisely and clearly defined.
2. Develop a mathematical model for the problem. In modeling mathematical structures that are best
suited are selected.
3. Data structures and program structures used to develop a solution are planned.
4. The most common method for designing an algorithm is step wise refinement. Step wise refinement
breaks the logic into series of steps. The process starts from converting the specifications of the
module into an abstract description of an algorithm containing a few abstract statements.
5. Once algorithm is designed, its correctness should be verified. The most common procedure to
correct an algorithm is to run the algorithm on various number of test cases. An ideal algorithm is
characterized by its run time and space occupied.

1.3 The analysis of algorithm has two phases:


1. Priori analysis: In this analysis we find some functions which bounds algorithm time and space
complexities. By the help of these functions it is possible to compare the efficiency of algorithms.
2. Posterior Analysis: Estimating actual time and space when an algorithm is executing is called
posterior analysis.
Priori analysis depends only on the number of inputs and operations done, Where as posterior analysis
depends on both machine and language used, which are not constant. Hence analysis of most of the
algorithms is made through priori analysis.

1.4 Time & Space complexities :


a) Space complexity:
It is defined as the amount of memory need to save and execute an algorithm. The memory space
needed for an algorithm has two parts. One is fixed part, such as memory needed for local variables,
constants, instructions etc. Second one is variable part, such as space needed for reference variables, stack
space etc. They depend upon the problem instance.
The space requirement S(P) of an algorithm P can be written as S(P) = c + Sp, were c is a
constant (representing fixed part). Thus while analyzing an algorithm , Sp (variable part) is estimated.
b) Time complexity:
The time taken by a program is the sum of the compile time and the run time. Compile time does
not depend on the algorithm. Run time depends on the algorithm.The time complexity of an algorithm is
given by the number of steps taken by the algorithm to compute the function it was written for. The
number of steps will be computed as a function of the number of inputs and the magnitude of inputs.
The time T(P) taken by a program is the sum of compile and run time. The compile time does not
depend upon the instance characteristics, hence it is fixed. Where as run time depends on the
characteristics and it is variable. Thus while analyzing an algorithm run time T(P) is estimated.

Order of Magnitude :
It refers to the frequency of execution of an instruction / statement. The order of magnitude of an
algorithm is sum of all frequencies of all statements. The running time of an algorithm increases with size
of input and number of operations.
2. DATA STRUCTURES

DATA : It is a group of elementary items such as integers, characters, bits etc.

DATA TYPE : A data type is a set of values and a set of operations on those values. Data types are
broadly classified into three categories. They are atomic data type, structured data type and abstract data
type.

Atomic data Type : If the values of a data type are single entities and not able to subdivide, then they
are called atomic data type.

Structured data type : Tools such as arrays, files and pointers with which we can build new types of
data elements are called structured data types or derived data type.

Abstract data type : It refers to the basic mathematical concept that defines data type. It has two parts
first is description of the way in which the components are related to each other and second is operations
performed on those elements.
We can also define a abstract data type as a set of mathematical abstractions.

DATA STRUCTURE : The possible ways in which these elementary data items are logically related are
defined by different data structures. A data structure specifies the storage representation and organization
of various data items in memory.

Every data structure can be defined by a triple – Functions(F), Domain (D) and Axioms (A).

Functions : They define the operations performed on data structures such as creation, deletion etc.
Domain : The set of values that can be stored by using the data structure.
Axioms : The set of rules and regulations followed by the data structure.

1.1 TYPES OF DATA STRUCTURES

Data structures are mainly classified into two types. They are
1. Primitive data structures : The data structure on which machine level instruction are operated
directly upon them are known as primitive data structures. Ex : Integers, reals, characters etc.
elements, but they must be in same order as that of array elements. The general rule is that
rightmost subscript increases most rapidly and leftmost subscript increases least rapidly.

2. LINKED REPRESENTATION

A data structure to be linear for a given element ‘d’, there must exist at least
two adjacent elements. If the elements in a list are logically adjacent but not
physically, then they are said to be linked lists. A linked list consists of a series of
structures which are not necessarily adjacent in memory. These structures are
normally called as ‘nodes’.
The first and last nodes of the list are called as head and tail of the list.
A new node can be created and linked by the help of pointer at any time. To insert a
new node into the existing list it takes O (1). Space and time taken to create a list
with n – nodes is in the order of O (log n).

Properties of linked Lists:

1. It is dynamic in nature.
2. Elements are logically adjacent but nor physically.
3. Address field of each element is stored in the memory itself.
4. Address of an element is found by using the pointers of previous element.
5. Accessing mode is always sequential.
6. More memory is required.
7. Insertion and deletion of elements does not need any movement of data in the
list.
8. If a pointer is lost, remaining part of the list is lost.

DYNAMIC MEMORY MANAGEMENT

If the data size is constant and does not change throughout the execution of
a program, then a fixed size of memory is assigned for it. This is known as static
memory management. If data keeps changing throughout the program, then
memory is assigned during run time according to changes in data length. This is
known as dynamic memory management. It will permit to allocate additional
memory or to delete unwanted memory at run time.

C ++supports a built in function to support dynamic memory management.

MALLOC :
‘malloc’ is used to reserve a block of memory for specified size.
General format of malloc
Pointer name = (data type*) malloc (size of the block);

CALLOC :
‘calloc’ is used to reserve a multiple blocks of memory for specified size.
General format of calloc
Pointer name = (data type*) calloc (number of blocks, size of each block);

REALLOC :
‘realloc’ is used to reallocate the memory which is already assigned for a data type.
General format for realloc
Pointer name = realloc(pointer, new size);

SINGLY LINKED LIST


A singly linked list consists of a series of structures instead of elements,
which are not necessarily adjacent in memory. The order of the elements is given
by links from one item to next. Each structure of list is called a node and consists of
two fields, one containing the information to be stored and the other is the pointer
to next structure.
Since all the nodes in the linked list are anonymous nodes, it is difficult to
distinguish the starting point and ending point of a list. Hence a dummy node
known as ‘head’ is introduced at the starting point of the list. Head consists of
address of first element in the list. Head also has a similar structure of that of a
node in the list. Similarly to indicate end of the list, the pointer of last element in
the list is made null.

Algorithm to create a node in linked list :

1. Initially define the structure of the node in the list. Each node has two
elements, one is information of int or char or float type and other is pointer
indicating the address of next node, of pointer type.

Struct node
{int inf;
Node*ptr}
}

2. Define a dummy node head which is equal to null.

Node *head;
Head=null;

3. Create a node and assign its address to a pointer temp.

Temp=(node*)malloc(sizeof(node));

4. Dot operator or arrow operator can be used to access the elements in each
node. Enter the information into the information filed and assign the head value to
the pointer field. Make temp pointer as head so that head becomes starting point of
the list.

Temp->inf=x;
Temp->ptr=head;
Head=temp;

5. Repeat step 3 and 4 until the stopping condition is reached.

For(1=0;1<10;1++)
Repeat step3.

Algorithm to insert an element x as last element in the list :

1. Create a ‘new’ node, and insert the element x in its information field.

New = (node*) malloc(sizeof(node));


New->inf = x;

2. Travel through the list until you reach the end of the list, by the help of a
temporary pointer.
Temp=head;
While(temp->ptr)=NULL)
Temp=temp->ptr;

3. Since the new element must become last element, its pointer must become null.
The last element in the list, pointer must indicate new element.

New->ptr=NULL;
Temp->ptr=new;

Algorithm to insert an element x as predecessor of an element y in the list


:

1. Create a ‘new’ node, and insert the element x in its information field.

New=(node*)malloc(sizeof(node));
New->inf=x;

2. Travel through the list until you reach the element y, by the help of a temporary
pointer.

Temp = head;
While(temp->inf !=y)
Temp=temp->ptr;

3. Since x must become predecessor of y, new mode pointer must indicate y and
pointer indicating y must indicate new node.

New->ptr = temp;
Temp=new;

Algorithm to insert an element x as successor of an element y in the list:

1. Create a ‘new’ node, and insert the element x in its information field.
New=(node*)malloc(size of(node));
New->inf=x;

2. Travel through the list until you reach the element y, by the help of a temporary
pointer.

Temp = head;
While(temp->inf 1=y)
Temp=temp->ptr;

3. Since x must become successor of y, y’s pointer must indicate new node and
new node pointer must indicate the y’s previous successor.

New->ptr = Temp->ptr;
Temp->ptr=new;
Algorithm to delete first element in the list:

1. Make head equal to the address of its next pointer. Therefore the head indicates
the second element instead of first element. Then free the first node so that it is
deleted.

Temp=head;
Head=head->ptr;
Free(temp);

Algorithm to delete last element in the list :

1. Travel through the list until you reach the end of the list.

Temp=head;
While(temp->ptrl=null)
Temp=temp->ptr;

2. Make the pointer of last but one element as null, so that last element is deleted
from the list.

Temp=null;

CIRCULAR LINKED LIST

One of the major draw back in SLL is, once we have reached a node we
cannot travel in backward direction. If we change the next address of last node in a
SLL, as the address of the first node instead of NULL, then it is called circular linked
list.
One of the disadvantage of circular linked list is endless looping. To prevent
it we can insert a header node containing an element which distinguished it from
other nodes.

Algorithm to create a circular linked list :

1. Initially define the structure of the node in the list. Each node has two elements,
one is information of int or char or float type and other is pointer to next node of
pointer type.

Struct node
{int inf;
Node*ptr;
};
2. Define a dummy node head which acts as starting point of CLL.

Node*head;
Temp=head;

3. Create a node and assign its address to a pointer temp.

Temp=(node*)malloc(sizeof(node));

4. Dot operator or arrow operator can be used to access the elements in each
node. Enter the information in information field and make the current pointer as
next pointer. Create a node with the help of this pointer.

Temp->inf = x;
Temp -> ptr – (node*) malloc (size of (node));
Temp = temp -> ptr;

5. Repeat step 4 until the stopping condition is reached.

6. Assign the head address to the pointer of last node, such that it indicates the
head.
Temp = head;

DOUBLY LINKED LIST

In a circular linked list to find the previous element, we must travel along the
list. It takes a long time. Where as in a doubly linked list, it is very easy to find
previous element. Here each node has two pointers. One, known as previous
pointer always representing predecessor of current element and other is known as
next pointer always representing successor of current element. By the help of
these pointers we can travel both in forward and backward directions. Also it is
very easy to delete an element, as links to both previous node and next node exist
at all nodes.

Algorithm to create a doubly linked list:

1. Initially define the structure of the node in the list. Each node has three
elements, one is information of int or char or float type, second one is a pointer to
next node of pointer type and the third one is a pointer to previous node of pointer
type.

Struct node
{ node*prevptr;
Int inf;
Node*nextptr;
};

2. Define a dummy node head which is equal to null.


Node*head;
Head=null;

3. Create a node and assign its address to a pointer temp.

Temp = (node*)malloc(sizeof(node));

4. Dot operator or arrow operator can be used to access the elements in each
node. Enter the information into the information filed and assign the head value to
the pointer field. Make temp pointer as head so that head becomes starting point of
the list.

Temp->inf=x;
Temp->nextptr=head;
Head=temp;
Temp=(node*)malloc(sizeof(node));
Head->prevptr=temp;

5. Repeat step 4 until the stopping condition is reached.

6. Make previous pointer of first node as null.

Head->prevptr=NULL;

4.STACKS

A stack is a list in which all it sertions and deletions of elements are made at one end, namely the
top of the stack. A stack is a storage device which allows to store information always on the top of the
stack and also to remove the information present on the top of the stack. Thus it operates on the basis of
LIFO (last in first out).

It also has an imaginary index known as Stack Pointer. A stack pointer always show the address
of the element present at the top of the stack.

Types of Stacks : There are two types of stacks. They are memory stack and register stack. If a
portion of memory unit is assigned for creating stack, then it is said to be memory stack. If a set of
registers are used to develop the stack then it is said to be register stack. A memory stack can be allowed
to grow until it occupies entire memory, where as a register stack is of limited size.

Operations on Stack : There are three fundamental operations that can be performed on stack. They are
1. PUSH : Inserting a new element into the stack is known as push operation. When a new element is
to be inserted into the stack, always it is placed at the top of the stack.
2. POP : Removing an element from the stack is known as pop operation. When an element is
removed from the stack, always the element that is present at the top of the stack is removed.
3. PEEP : When the value of a specific element present in the stack is to be viewed, it can be used.

Algorithm to create a Stack :

1. Declare an array of suitable size N, as a stack. Declare a variable SP as a stack pointer and
initialize to 0. IF stack pointer is 0 then it is said to be stack is empty.
Fig.
Int stack[N];
Int Sp;
Sp=-1;

Algorithm to insert an element into the Stack :

1. If the stack pointer is equal to size of the stack N, then it is not possible to insert a new element and
the status of stack is declared as ‘stack is full’.

Fig.
If (SP = = N-1)
Printf(“stack is full”);

2. Other wise, SP is incremented always by 1 and the new element is entered into the array at the
position S [SP],

Fig.
SP = SP + 1;
Stack [SP] = x;
Algorithm to delete an element from the Stack;

1. If the stack pointer is equal to 0, then it is not possible to delete the element from the stack and the
status of the stack is declared as ‘stack is full’.

If (SP = = -1)
Printf(“stack is empty”);

2. Otherwise, the element on the top of the stack is removed and stack pointer is decrements by 1.

Fig.

X=Stack[SP];
SP = SP – 1;

Applications of Stack :
1. Balancing Symbols in an expression : Most of the syntax errors are due to misplacement of braces
or starters etc. Every right brace or parenthesis must respond to their left counterparts. Thus by
using stack we can check whether parenthesis are balanced or not.

Algorithm :
1. Create an empty stack.
2. Read characters until end of file.
3. If the character is an open (push it onto stack.
4. If it is a close) then if it is on stack display error.
5. Otherwise, pop the stack.
6. If popped symbol is not corresponding symbol of opening display error.

2. Evaluation of expressions : Generally, expressions are represented by infix notations. When infix
notation is used we must specify the precedence of operators. Thus if we rewrite the expression in
postfix it is very easy to evaluate the expressions. To convert infix to post fix, the operations which
have highest precedence must be converted first.
Ex : A + B * C -> ABC*+

Each operator in a post fix string refers to previous two operands in the string. Each time When
we read an operand. We push onto a stack. When we reach an operator, its operands will be the top two
elements on the stack. Then we can pop them and perform the operation and push the result on to the
again.

Algorithm for converting infix to post fix :


1. Read each character, if character is operand push into stack.
2. Otherwise pop the next two elements on the top of the stack.
3. Perform the specified operation and push it onto stack.
4. Repeat the process until the end of the input string.

3. Using for function Calls : When a function is called all the variables local to that calling function
must be saved. Otherwise the variables used in the function may overwrite the variables used in the
program. To implement recursion a stack is needed. When a sub program invokes a series of other
sub programs that invokes first sub program, the variables in calling programs must is saved in
stack.

QUEUES

A queue is defined as a list in which all additions to the list are made at one end and all deletions
from the list are made at other end. Placing an element into the queue is known as insertion. Always
insertion of a new element is made at the rare end of the queue. Removing an element from the queue is
known as deletion. Always deletion of an element is made from the front end of the queue.

A queue has two pointers. They are front pointer, which shows always the address of the element
to be removed from the queue and rare pointer, which shows always the address of the element that is to
be entered into the queue.

Algorithm to create a Queue :

1. Declare an array of suitable size N, as a queue. Declare two integer variables FP and RP as front
pointer and rare pointer and initialize them to 0. If both pointers are 0, then it is said to be queue is
empty.

Int Queue[N];
Int Fp,Rp;
Fp=Rp= - 1;

Algorithm to Insert an element into the queue :

1. If the rare pointer is equal to size of the queue N, then it is not possible to insert a new element and
the status of queue is declared as ‘queue is full’.

If (RP == N-1)
Printf(‘queue is full’);

2. Other wise, Rp is incremented always by 1 and the new element is entered into the array at the
position queue [RP].
RP=RP+1;
Queue [RP] = x;

Algorithm to delete an element from the queue:

1. If the front pointer is equal to rear pointer, it represents there is only one element in the queue.

If ((RP = FP) && (RP! = -1))


X = queue [FP];
RP = FP – 1

2. If front pointer and rare pointer both are equal to -1 then the queue is said to be empty. Then the
status of the queue is declared as ‘queue is empty’.

If(RP = FP = -1)

Printf(‘queue is empty’);

3. Otherwise, the element in the queue is removed and front pointer is incremented by ….

X = queue [FP];
FP = FP + 1;

Applications of Queues :

1. In computer systems there are many number of queues of tasks waiting for access to memory and
I/O devices or processor. Also within a single program there may be multiple requests to be kept in
a queue.
2. Inter process communication needs to send messages from one process to other. With the help of
queues we can transmit these messages.

Disadvantage of Linear Queue :

Major disadvantage in linear queue is, both front pointer and rare pointer are never decreased.
Even if there are not more than two items in a queue a large amount of memory is needed for additions
and deletions. Similarly if queue is implemented by the help of arrays storage space at the beginning of
array is never used. Thus for some time queue reaches the end of storage space. To over come this,
circular queues are developed.

CIRCULAR QUEUES

In circular queue elements are added and removed in a circular manner.


Always front pointer chases rare pointer. Unless the queue is never occupied
circular queue never goes out off space.
Both pointers are incremented in modular arithmetic way. When the pointers
crosses N-1, they again start from 0.

Algorithm to create a circular queue;


1. Declare an array of suitable size N, as a queue. Declare two integer variables FP
and RP as front pointer and rare pointer and initialize them to -1. If both pointers
are -1, then it is said to be queue is empty.

Int CQ[N];
Int Fp, Rp;
Fp = Rp = -1;
Count = 0;

Algorithm to Insert an element into the queue :

1. If the rare pointer is equal to size of the queue N and front pointer is 0 or rare
pointer is exactly behind the front pointer and not equal to -1, then it is not
possible to insert a new element and the status of queue is declared as ‘queue
is full’. Also we can use a counter to count number of entries in the queue. If
the counter is equal to N, then queue is said to be full.

If ((Rp = = N – 1, && (Fp = = 0) || (Rp = FP – 1) *&& (RP > -1)


Printf(‘queue is full’);
Or
If(count = = 0)
Printf(‘queue is full’);

2. Other wise, RP is incremented always by (RP mod N) + 1 and the new element
is entered into the array at the position queue [RP].

RP = (RP mod N) + 1;
CQ [RP] = x;
Count = count + 1;

Algorithm to delete an element from the queue :

1. If the front pointer is equal to rear pointer, it represents there is only one
element in the queue.

IF (RP = FP)
X = CQ [Fp];
RP = FP = -1;

2. If front pointer and rare pointer both are equal to -1 then the queue is said to
be empty. Then the status of the queue is declared as ‘queue is empty’. If
count is equal to 0 then we can say that queue is empty.

If(Rp = Fp = -1)
Printf(‘queue is empty’);
Or
Count = = 0;
Printf (‘queue is empty’);

3. Otherwise
X = CQ[FP];
FP = (FP mod N) + 1;
Count = count – 1;

PRIORITY QUEUE

A priority queue is composed of several independent queues, each having tis


own priority. The elements to be inserted into the queue have again their own
priority. Depending on the priority of the element it is entered into that particular
queue. When an element is to be removed the element in the highest priority
queue is removed first. If an element from the lower priority must be removed all
the elements in the higher priority must be empty.

DOUBLY ENDED QUEUE

If both deletion and insertion are possible at the two ends of a linear queue
then it is said to be doubly ended queue.

STACK USING LINKED LIST

Stack can be built by the help of a, singly linked list. One end of the list is
made null since the stack can be accessed at only one end. The operations on the
stack PUSH and POP are slightly modified as PUSHNODE and POPNODE.

When we want push a new element x into the stack, a new node is created
with x at its information field and it is inserted as the first element in the list.

When we want to pop an element x which is on the top of the stack, the first
node in the list is deleted.

The number of elements in the list is equal to the size of the stack.

Algorithm to create a stack :

1. Initially define the structure of the node in the list. Each node has two elements,
one is information of int or char or float type and other is pointer indicating the
address of next element in the stack.

Struct node
{ int inf;
Node*ptr;
};

Node*stack pointer :

The address of the first element in the list is assigned to stack pointer.

Algorithm to push an element x on to the top of the stack ;


1. It is same as inserting the element as first element of the list. Create a ‘new’
node, and insert the element x in its information field.

New=(node*)malloc(sizeof(node));
New->inf=x;

2. Since the new element must become first element, its pointer must indicate the
previous first element i.e. stack pointer and now new must become the stack
pointer of the list.

New->ptr=stackpointer;
Stackpointer=new;

Algorithm to pop an element at the top of the stack :

1. It is same as deleting the first element of the list. Assign the stack pointer the
address of its next pointer. Therefore the stack pointer indicates the second
element instead of first element. Then free the first node so that it is deleted.

Temp=Stackpointer;
Stackpointer=stackpointer->ptr;
Free(temp);

QUEUES USING LINKED LIST

Queue can be built by the help of a singly linked list. The operations on the
queue insertion and deletion are slightly modified as INSERTNODE and DELETE
NODE.

When we want insert a new element x into the queue, a new node is created
with x at its information field and it is inserted as the next element in the list i.e., it
is inserted at the rear end of the list.

When we want to delete an element x which is in the first position in queue


i.e., the first node in the list is deleted.

The number of elements in the list is equal to the size of the queue.

Algorithm to create a queue :

1. Initially define the structure of the node in the list. Each node has two elements,
one is information of int or char or float type and other is pointer indicating the
address of next element in the queue.
Struct node
{ int inf;
Node*ptr;
};
Node*frontpointer;
Node*rearpointer;
The address of the first element in the list is assigned to front pointer and the
address of last element is assigned to rear pointer.

Algorithm to insert an element x into the queue :

1. It is same as inserting an element at the end of the list. Create a ‘new’ node,
and insert the element x in its information field.
New=(node*)malloc(sizeof(node));
New->inf=x;

2. Since the new element must become the last element, travel through the list
until the last element is reached. The pointer of the last element in the list must
indicate the new element and the pointer of new element must be made null. The
rear pointer of the queue must indicate the address of the last node.

New->pu=null;
Temp=new;
Rearpointer=new;

Algorithm to delete an element from the queue :

1. It is same as deleting the first element from the list. Assign the front pointer, the
address of its next pointer. Therefore the front pointer indicates the second
element instead of first element. Then free the first node so that it is deleted.

Temp=frontpointer;
Frontpointer=frontpointer->ptr;
Free(temp);
Programs:

1. CREATING SIMPLE LINKED LIST

# include <iostream.h>
# include <alloc.h>
# include<conio.h>

struct link
{
int info;
link *next;
};

class creat_link
{
private:
int i;
int number ;
link *start;
public:
creat_link()
{
start = NULL; // Shows empty list
}
void creat_link_list(link *);
void display(link *);
};

void creat_link :: creat_link_list(link *node)


{
char ch;
cout<<"\n Input choice n for break: ";
i = 0;
ch = getche();
while(ch !='n')
{
cout<<"\n Input the node :"<<(i+1)<<" : ";
cin>>node->info;
node->next = (struct link* ) malloc(sizeof(struct link));
node = node->next;
node->next = start;
i++;
cout<<"\n Input choice n for break: ";
ch = getche();
}
}

void creat_link:: display(link *node)


{
cout<<"\n Values of the entered nodes are as follows:\n";
while (node->next)
{
cout<<" "<< node->info;
node = node->next;
}
}

void main()
{
creat_link link_c;
link *node = (link *)malloc(sizeof(link));
link_c.creat_link_list(node);
link_c.display(node);
}

2./ DELETING A NODE FROM A SIMPLE LINKED LIST WHEN INFORMATION OF A NODE
IS GIVEN

# include <iostream.h>
# include <alloc.h>
# include<conio.h>

struct link
{
int info;
struct link *next;
};

class D_node
{
private:
int i;
int number ;
link start, *previous;
public:
void Delete_node(link *);
void creat_node(link *);
};

// Create linked list

void D_node :: creat_node(link *node)


{
char ch;

i = 0;

start.next = NULL; // Empty list


node = &start; // Point to the start of the list

cout<<"\n Input choice n for break: ";


ch = getche();

while(ch != 'n')
{
node->next = (struct link* ) malloc(sizeof(struct link));
node = node->next;
cout<<"\n Input the node :"<<(i+1)<<" : ";
cin>>node->info;
node->next = NULL;

cout<<"\n Input choice n for break: ";


ch = getche();

i++;

}
cout<<"\n Total nodes = "<<i;

node = start.next;
cout<<"\n Created list is as follows:\n";
while (node)
{
cout<<"\n "<<node;
cout<<" "<< node->info;
node = node->next;
}
}

// Removing a node

void D_node:: Delete_node(link *node)


{
node = start.next;
previous = &start;

int node_number = 1;
int delete_node;

cout<<"\n Input information of a node you want to delete:";


cin >> delete_node;
while(node)
{

if(node->info == delete_node)
{
cout<<"\n Position of the information in the lisy is :"<<node_number;
previous->next = node->next;
delete(node);
break ;
}
else
{
node = node->next;
previous = previous->next;
}
}

// Display the list

node = start.next;
cout<<"\n After deleting a node list is as follows:\n";
while (node)
{
cout<<"\n "<<node;
cout<<" "<< node->info;
node = node->next;
}
}

void main()
{
D_node del_node;
link *node = (link *) malloc(sizeof(link));
del_node.creat_node(node);
del_node.Delete_node(node);
}

3. DELETING LAST NODE FROM A SIMPLE LINKED LIST

# include <iostream.h>
# include <alloc.h>
# include<conio.h>

struct link
{
char info;
struct link *next;
};

class D_node
{
private:
int i;
int number ;
link start, *previous;
public:

void Delete_node(link *);


void creat_node(link *);
};

void D_node :: creat_node(link *node)


{
char ch;
i = 0;

start.next = NULL; // Empty list


node = &start; // Point to the start of the list

cout<<"\n Input choice n for break:";


ch = getche();

while(ch != 'n')
{
node->next = (struct link* ) malloc(sizeof(struct link));
node = node->next;
cout<<"\n Input the node :"<<(i+1)<<" : ";
cin>>node->info;
node->next = NULL;

cout<<"\n Input choice n for break:";


ch = getche();
i++;
}

node = start.next;
previous = &start;
cout<<"\n Created list is as follows\n";

while (node)
{
cout<<"\n "<<node;
cout<<" "<< node->info;
node = node->next;
}
}

// Removing a node

void D_node:: Delete_node(link *node)


{
int node_number = 0;

node = start.next;
previous = &start;

if (node == NULL)
{
cout<<"\n Underflow";
}

else

while(node)
{
node = node->next;
previous = previous->next;
node_number ++;
}
cout<<"\n Total Nodes = "<<node_number;

node = start.next;
previous = &start;

while(node_number != 1)
{
node = node->next;
previous = previous->next;
node_number --;
}
if(node_number == 1)
{
previous->next = node->next;
free(node);
}
// Display the list

node = start.next;
cout<<"\n After deleting last node list is as follows\n";
while (node)
{
cout<<"\n "<<node;
cout<<" "<< node->info;
node = node->next;
}
}

// Function main

void main()
{
D_node del_node;
link *node = (link *) malloc(sizeof(link));
del_node.creat_node(node);
del_node.Delete_node(node);
}

4. / REVERSING A LINKED LIST

#include <iostream.h>
#include <alloc.h>

struct link
{
int data;
link *next;
};

class reverse_list
{
public: int i, number;
link *start, *node, *previous, *current1, *counter;

public:
void display( link *);
void create_list(link *);
link * reverse(link *);
};

// Reversing the list

link * reverse_list :: reverse(link *start)


{

current1 = start;
previous = NULL ;

while( current1 != NULL )


{
counter = (link *)malloc(sizeof(link));
counter = current1->next ;
current1->next = previous ;
previous = current1 ;
current1 = counter;
}

start = previous;
return(start);
}

// definition of the function

void reverse_list :: display(link *node)


{
while (node != NULL)
{
cout<<" "<< node->data;
node = node->next;
}
}

// definition of the function

void reverse_list :: create_list(link *node)


{
int i;
int number;

cout<<"\n Input the number of nodes you want to create :";


cin>>number ;

// CREATE A LINKED LIST

for (i = 0; i < number ; i++)


{
cout<<"\n Input the node :"<<(i+1)<<" : ";
cin>>node->data;
node->next = (link* ) malloc(sizeof(link));
if( i == number - 1)
node->next = NULL;
else
node = node->next;

}
node->next = NULL;

// END OF CREATION

void main()
{
link *node;
link *p;

node = (link *) malloc(sizeof(link));


reverse_list rev_list;
rev_list.create_list(node);
cout<<"\n Original List is as follows:\n";
rev_list.display(node);
p = ( link *)malloc(sizeof(link));
p = rev_list.reverse(node);
cout<<"\n After reverse operation list is as follows:\n";
rev_list.display(p);
}

5. IMPLEMENTATION OF THE STACK USING ARRAYS

# include<iostream.h>
# include<stdio.h>
# include<string.h>
# include<ctype.h>

# define size 100

int top = -1;


int flag = 0;

class stacks
{
private: int stack[100];
int data;

public:
void push(int *, int);
int pop(int *);
void display(int *);
};

// Definition of the push function

void stacks :: push(int s[], int d)


{
if(top ==(size-1))
flag = 0;
else
{
flag = 1;
++top;
s[top] = d;
}
}

// Definition of the pop function

int stacks :: pop(int s[])


{
int popped_element;
if(top == -1)
{
popped_element = 0;
flag = 0;
}
else
{
flag = 1;
popped_element = s[top];
--top;
}
return (popped_element);
}

// Definition of the display function

void stacks :: display(int s[])


{
if(top == -1)
{
cout<<"Stack is empty";
}
else
{
for(int i = top; i>=0; --i)
cout<<" "<<s[i];
}
}

void main()
{
stacks s;
int stack[size];
int data;
char choice;
int q = 0;
int top = -1;

do
{
cout<<" \nPush->i Pop->p Quit->q:";
cout<<"\nInput the choice : ";
do
{
cin>>choice;
choice =tolower(choice);
}while(strchr("ipq",choice)==NULL);
cout<<"Your choice is ->"<<choice;

switch(choice)
{
case 'i' :
cout<<"\n Input the element to pushed:";
cin>>data;
s.push(stack,data);
if(flag)
{
cout<<"\n After inserting ";
s.display(stack);
if(top == (size-1))
cout<<"\n Stack is full";
}
else
cout<<"\n Stack overflow after pushing";
break;

case 'p' : data = s.pop(stack);


if(flag)
{
cout<<"\n Data is popped:"<<data;
cout<<"\n Rest data in stack is as follows:\n";

s.display(stack);
}
else
cout<<"\n Stack underflow";
break;
case 'q': q = 1;
}
} while(!q);
}

6. STACK IMPLEMENTATION USING LINKED LIST

# include<iostream.h>
# include<malloc.h>

struct link
{
int info;
link *next;
};

class stack_link
{
private: link *start;

public: void display(link *);


link *push(link *);
link *pop(link *);
int main_menu();
};

void stack_link :: display(link *rec)


{
while(rec != NULL)
{
cout<<" "<<rec->info;
rec = rec->next;
}
}

link * stack_link :: push(link *rec)


{
link *new_rec;
cout<<"\n Input the new value for next location of the stack:";

new_rec = (link *)malloc(sizeof(link));


cin>>new_rec->info;
new_rec->next = rec;
rec = new_rec;
return(rec);
}

link * stack_link :: pop(link *rec)


{
link *temp;

if(rec == NULL)
{
cout<<"\n Stack is empty";
}
else
{
temp = rec->next;
free(rec);
rec = temp;
cout<<"\n After pop operation the stack is as follows:\n";
display(rec);
if(rec == NULL)
cout<<"\n Stack is empty";
}
return(rec);
}

int stack_link :: main_menu ()


{
int choice;
do
{
cout<<"\n 1<-Push ";
cout<<"\n 2<-Pop";
cout<<"\n 3<-Quit";
cout<<"\n Input your choice :";
cin>>choice;
if(choice <1 || choice >3)
cout<<"\n Incorrect choice-> Try once again";
} while(choice <1 || choice >3);

return(choice);
}

// main function

void main()
{
stack_link stack;
link *start ;
int choice;
start = NULL;
do
{
choice = stack.main_menu();
switch(choice)
{
case 1:
start = stack.push(start);
cout<<"\n After push operation stack is as follows:\n";
stack.display(start);
break;
case 2:
start = stack.pop(start);
break;
default : cout<<"\n End of session";
}
} while(choice != 3);
}

7. INSERTION AND DELETION IN A QUEUE ARRAY IMPLEMENTATION


# include<iostream.h>
# include<conio.h>
# include<string.h>
# include<ctype.h>
# include<process.h>

# define size 10

class Queue
{
public: int rear, front;
int ch;
int q[size];

public: Queue()
{
rear = front = 0;
}
void Insert_queue();
void Delete_queue();
void Display_queue();

};

// Function to create queue

void Queue :: Insert_queue()


{
cout<<"\n Input the element :";
cin>>ch;
if(rear < size)
{
rear ++;
q[rear] = ch ;
if(front == 0)
front = 1;
}
else
cout<<"\nQueue is overflow";
}

// Function to perform delete operation

void Queue :: Delete_queue() //char q[], char ch)


{
if (front == 0)
{
cout<<"\nUnderflow";
return ;
}
else
{
ch = q[front];

cout<<"\nElement deleted :"<<ch;


}
if(front == rear)
{
front = 0;
rear = 0;
}
else
front = front + 1;
}

// Output function

void Queue :: Display_queue() //char q[])


{
if (front == 0)
return;
for( int i = front ; i <= rear; i++)
cout<<" "<<q[i];
}

//Function main

void main()
{
Queue Q;
int k = 0;
char choice;

do
{
cout<<"\nInsert->i Delete->d Quit->q:";
cout<<"\nInput the choice : ";
do
{
cin>>choice;
choice = tolower(choice);
}while(strchr("idq",choice)==NULL);
cout<<"Your choice is ->"<<choice;

switch(choice)
{
case 'i' :
Q.Insert_queue();
cout<<"\nQueue after inserting ";
Q.Display_queue();
break;

case 'd' : Q.Delete_queue();


cout<<"\nQueue content after deleteion is as follows:\n";
Q.Display_queue();
break;

case 'q': k = 1;
}
} while(!k);
}

8. INSERTION AND DELETION IN A CIRCULAR QUEUE ARRAY IMPLEMENTATION

# include<iostream.h>
# include<conio.h>
# include<string.h>
# include<ctype.h>
# include<process.h>

# define size 6

int L, U; // L means lower bound U means upper bound


class Queue
{
public: int rear, front;
int ch;
int q[size];

public: Queue()
{
rear = front = -1;
}
void Insert_queue();
void Delete_queue();
void Display_queue();

};

// Function to create queue

void Queue :: Insert_queue()


{
if ((front == 0) && (rear == size-1))
{
cout<<"\n Overflow";
rear = 1;
return;
}
else
if (front < 0) // Insert first element
{
front = 0;
rear = 0;
cout<<"\nInput the element :";
cin>>ch;
q[rear] = ch ;
}
else
if (rear == size-1)
{
rear = 0;
cout<<"\n Input the element :";
cin>>ch;
q[rear] = ch ;
}

else
{
rear ++;
cout<<"\n Input the element :";
cin>>ch;
q[rear] = ch ;
}
}

// Function to perform delete operation

void Queue :: Delete_queue()


{
if (front < 0)
{
cout<<"\nUnderflow";
return ;
}
ch = q[front];
q[front] = NULL;
cout<<"\nElement deleted :"<<ch;
if(front == rear)
{
front = -1;
rear = -1;
}
else
if ( front == size-1)
{
front = 0;
}
else
{
front++ ;
}

// Output function

void Queue :: Display_queue()


{
if (front < 0)
return;
if ( rear >= front)
{
for( int i = front; i <= rear; i++)
{
cout <<"\n i="<<i;
cout<<" "<<q[i];
}
}
else
{
for( int i = front; i < size; i++)
{
cout <<"\n i="<<i;
cout<<" "<<q[i];
}
for( i = 0; i <= rear; i++)
{
cout <<"\n i="<<i;
cout<<" "<<q[i];
}
}
}

//Function main

void main()
{
Queue Q;
int k = 0;
char choice;

do
{
cout<<"\nInsert->i Delete->d Quit->q:";
cout<<"\nInput the choice : ";
do
{
cin>>choice;
choice = tolower(choice);
}while(strchr("idq",choice)==NULL);
cout<<"Your choice is ->"<<choice;

switch(choice)
{
case 'i' :
Q.Insert_queue();
cout<<"\nQueue after inserting ";
Q.Display_queue();
break;

case 'd' : Q.Delete_queue();


cout<<"\nQueue content after deleteion is as follows:\n";
Q.Display_queue();
break;

case 'q': k = 1;
}
} while(!k);
}
UNIT IV
Dictionaries, Linear list representation, skip list representation, operations-
insertion, deletion and searching. Hash table representation, hash functions,
collision resolution-separable chaining, open address linear probing, quadratic
probing, double hashing, rehashing, extendable hashing, comparison of hashing and
skip lists.

Dictionaries
Dictionaries are sometimes found in other languages as ``associative memories'' or ``associative
arrays''. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by
keys, which are strings and numbers.
A dictionary is an unordered set of key: value pairs {k,v}, with the requirement that the keys are
unique (within one dictionary).
A pair of braces creates an empty dictionary: {}.
Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs to
the dictionary; this is also the way dictionaries are written on output.
For example in a dictionary containing student records, the key may be student ID and the value
may be student name, address, grade etc.
The main operations on a dictionary are storing a value with some key and extracting the value
given the key. It is also possible to delete a key:value pair with del. If you store using a key that
is already in use, the old value associated with that key is forgotten. It is an error to extract a
value using a non-existent key.
The keys() method of a dictionary object returns a list of all the keys used in the dictionary, in
arbitrary order (if you want it sorted, just apply the sort() method to the list of keys). To check
whether a single key is in the dictionary, either use the dictionary's has_key() method or the in
keyword.
Here is a small example using a dictionary:

You might also like