0% found this document useful (0 votes)
13 views74 pages

Data Structure Array,Linklist, Stack , Queue Notes

The document provides an introduction to data structures, algorithms, and their classifications, emphasizing the importance of data organization for efficient processing. It discusses various data structures such as arrays, linked lists, stacks, and queues, along with their operations and characteristics. Additionally, it covers abstract data types (ADT) and highlights the significance of algorithm performance measured by time and space complexity.

Uploaded by

johnwick.x2777
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views74 pages

Data Structure Array,Linklist, Stack , Queue Notes

The document provides an introduction to data structures, algorithms, and their classifications, emphasizing the importance of data organization for efficient processing. It discusses various data structures such as arrays, linked lists, stacks, and queues, along with their operations and characteristics. Additionally, it covers abstract data types (ADT) and highlights the significance of algorithm performance measured by time and space complexity.

Uploaded by

johnwick.x2777
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Unit-I

Introduction to Data vs Information - Data Structures - Classification – Abstraction - Abstract data


types (ADT) - Array - characteristics - Storage Representations. Array Order Reversal- Recursion
Array operations, Algorithm-complexity – Time and Space trade off.

I. ALGORITHM
An algorithm is a well-defined computational procedure having well defined steps for solving
a particular problem. Algorithm is finite set oflogic or instructions, written in order for
accomplishing the certain predefined task.

Each algorithm must have:


• Specification: Description of the computational procedure.
• Pre-conditions: The condition(s) on input.
• Body of the Algorithm: A sequence of clear and unambiguous instructions.
• Post-conditions: The condition(s) on output.

Characteristics of an Algorithm
An algorithm must follow the mentioned below characteristics:
• Input: An algorithm must have 0 or well- d e f i n e d inputs.
• Output: An algorithm must have 1 or well-defined outputs, and should match with the
desired output.

• Feasibility: An algorithm must be terminated after the finite number of steps. •


Independent: An algorithm must have step-by-step directions which is independent of any
programming code.

• Unambiguous: An algorithm must be unambiguous and clear. Each of their steps and
input/outputs must be clear and lead to only one meaning.
The performance of algorithm is measured on the basis of following properties: • Time
complexity: It is a way of representing the amount of time needed by a program to run to the
completion.

• Space complexity: It is the amount of memory space required byan algorithm, during a
course of its execution. Space complexity is required in situations when limited memory is
available and for the multi user system.
2
2.INTRODUCTION TO DATA STRUCTURES
2.1 Data
In the modern context, data stands for both singular and plural. Data means a value or set of
values. Data can be defined as an elementaryvalue or the collection of values, for example,
student’s name and its idare the data about the student.
2.2 Structure
A building is a structure. A bridge is structure. In general, a structureis made up of components.
It has a form or shape. It is made up of parts.A structure is an arrangement of and relations between
parts or elements.
2.3 Data Structures
A data structure is an arrangement of data elements. Data Structure can be defined as the group
of data elements which provides an efficient way of storing and organizing data in the computer so
that it can be used efficiently. Some examples of Data Structures are arrays, Linked List, Stack,
Queue, etc. Data Structures are widely used in almost every aspectof Computer Science i.e.
Operating System, Compiler Design, Artificial Intelligence, Graphics and many more.

2.3.1 Needs
As applications are getting complex and amount of data is increasing day by day, the following
issues might be araised:

Processor speed: To handle very large amount of data, high speed processing is required, but as
the data is growing day by day tothe billions of files per entity, processor may fail to deal with that
much amount of data.
Data Search: Consider an inventory size of 106 items in a store;if our application needs to search
for a particular item, it needs to traverse 106 items every time, results in slowing down the search
process.

Multiple requests: If thousands of users are searching the data simultaneously in a web server, it
fails to process the requests.

In order to solve the above problems, data structures are used. Data is organized to form a data
structure in such a way that all items arenot required to be searched and required data can be
searched instantly.
Data structures are important for the following reasons
1. Data structures are used in almost every program or software system. 2. Specific data structures
are essential ingredients of many efficient algorithms, and make possible

3
the management of huge amounts of data, such as large integrated collection of databases. 3.
Some programming languages emphasize data structures, rather than algorithms, as the key
organizing factor in software design.
Advantages of Data Structures
Efficiency: Efficiency of a program depends upon the choice of data structures. For example:
suppose, we have some data and we need to perform the search for a particular record. element.
Hence, using array may not be very efficient here.

Reusability: Data structures are reusable, i.e. once we have implemented a particular data
structure, we can use it at any other place.

Abstraction: Data structure is specified by the ADT which provides alevel of abstraction. The
client program uses the data structure through interface only, without getting into the
implementation details.

3.Classification of Data Structure


The data structure is classified into two different types, primitive and non-primitive data
structures is shown in Fig.1.

Primitive Data Structures


Simple data structure can be constructed with the help of primitivedata structure. A primitive data
structure used to represent the standard data types of any one of the computer languages. Variables,
pointers, structures, unions, etc. are examples of primitive data structures.

Non Primitive Data Structures


Non Primitive Data Structures are classified as linear or non-linear. Arrays, linked lists,
queues and stacks are linear data structures. Trees and Graphs are non-linear data structures.
Except arrays, all other data structures have many variations. Non Primitive data structure can be
constructed with the help of any one of the primitive data structure andit is having a specific
functionality. It can be designed by user.
4

Fig. 1 Classification of Data Structure


Linear Data Structures
A data structure is called linear if all of its elements are arranged in the linear order. In
linear data structures, the elements are stored in non-hierarchical way where each element has the
successors and predecessors except the first and last element. In linear data structure the elements
are stored in sequential order.

Types of Linear Data Structures are given below:


Arrays: An array is a collection of similar type of data items stored in consecutive memory
location and is referred by common name; each data item is called an element of the array. The
data type of the element may be any valid data type like char, int, float or double. The elements of
array share the same variable name but each onecarries a different index number known as
subscript.
Linked List: Linked list is a linear data structure which is used to maintain a list in the memory. It
can be seen as the collection of nodes stored at non-contiguous memory locations. Each node of
the list contains a pointer to its adjacent node. It is a collection of data of same data type but the
data items need not be stored in consecutive.
Stack: Stack is a linear list in which insertion and deletions are allowedonly at one end, called top.
It is a Last-In-First-Out linear data structure.
A stack is an abstract data type (ADT), can be implemented in mostof the programming

5
languages. It is named as stack because it behaveslike a real-world stack, for example, piles of
plates or deck of cards etc.

Queue: Queue is a linear list in which elements can be inserted only atone end called rear and
deleted only at the other end called front. It isa First-In-First-Out Linear data structure. It is an
abstract data structure, similar to stack. Queue is opened atboth end therefore it follows
First-In-First-Out (FIFO) methodology for storing the data items.

Operations applied on Linear Data Structure


The following list of operations applied on linear data structures
• Add an element
• Delete an element
• Traverse
• Sort the list of elements
• Search for a data element

Non-linear Data Structures


This data structure does not form a sequence i.e. each item or element is connected with two or
more other items in a non-linear arrangement.The data elements are not arranged in sequential
structure. Elements are stored based on the hierarchical relationship among the data. The following
are some of the Non-Linear data structures.

Trees: Trees are multilevel data structures with a hierarchical relationship among its elements
known as nodes. The bottom most nodes are called leaf node while the top most node is called root
node. Each node contains pointers to point adjacent nodes. Each node in the tree can have more
than one child except the leaf nodes whereas each node can have at most one parent except the root
node.
Graphs: Graphs can be defined as the pictorial representation of the set of elements (represented
by vertices) connected by the links known as edges. A graph is different from tree in the sense that
a graph can have cycle while the tree cannot have the one.

6
Operations applied on non-linear data structures
The following list of operations applied on non-linear data structures.
1. Add elements

2. Delete elements

3. Display the elements

4. Sort the list of elements

5. Search for a data element

4. ABSTRACT DATA TYPES


Abstract Data Type (ADT) is a type or class for objects whose behaviour is defined by a set
of value and a set of operations.
The definition of ADT only mentions what operations are to be performed but not how these
operations will be implemented. It does not specify how data will be organized in memory and
what algorithms will be used for implementing the operations. The process of providing only the
essentials and hiding the details is known as abstraction is shown in fig,2.
Fig. 2 Abstract Data Type

4.1 List ADT

• The data is generally stored in key sequence in a list which has a head structure consisting of
count, pointers and address of compare function needed to compare the data in the list is
shown in fig.3.

7
• The data node contains the pointer to a data structure and a self-referential pointer which
points to the next node in the list.

//List ADT Type Definitions

typedef struct node{

void *DataPtr;

struct node *link;

} Node;

typedef struct{

int count;

Node *pos;

Node *head;

Node *rear;

int (*compare) (void *argument1, void *argument2);

Fig.3 List ADT


} LIST;
A list contains elements of the same type arranged in sequential order and following
operations can be performed on the list.

• get() – Return an element from the list at any given position.

• insert() – Insert an element at any position of the list.


• remove() – Remove the first occurrence of any element from anon-empty list. •
removeAt() – Remove the element at a specified location from anon-empty list. •
replace() – Replace an element at any position by anotherelement.

• size() – Return the number of elements in the list.


• isEmpty() – Return true if the list is empty, otherwise returnfalse.
• isFull() – Return true if the list is full, otherwise return false.
The List ADT Functions is shown in Fig.4.

Fig. 4 List ADT Functions


4.2 Stack ADT
✱ In Stack ADT Implementation instead of data being stored in each node, the pointer to data
is stored.

✱ The program allocates memory for the data and address is passed to the stack ADT is shown in
Fig.5.

✱ The head node and the data nodes are encapsulated in the ADT. The calling function can
only see the pointer to the stack.

✱ The stack head structure also contains a pointer to top and countof number of
entries currently in stack.

✱ A Stack contains elements of the same type arranged in sequential order.

9
//Stack ADT Type Definitions

typedefstruct node{

void *DataPtr;
struct node *link;

} StackNode;

typedefstruct{
int count;

StackNode *top;

} STACK;

Fig. 5 Stack ADT

All operations take place at a single end that is top of the stackand following
operations can be performed:
• push() – Insert an element at one end of the stack called top.
• pop() – Remove and return the element at the top of the stack,if it is not empty. • peek()
– Return the element at the top of the stack withoutremoving it, if the stack is not empty. •
size() – Return the number of elements in the stack.
• isEmpty() – Return true if the stack is empty, otherwise returnfalse.
• isFull() – Return true if the stack is full, otherwise return false.
4.3 Queue ADT
✱ The queue Abstract Data Type (ADT) follows the basic design of the stack abstract data type
is shown in fig.6.

✱ A Queue contains elements of the same type arranged in sequential order. Operations take place at
both ends, insertion is done at theend and deletion is done at the front. Following operations can be
performed.

• enqueue() – Insert an element at the end of the queue.


• dequeue() – Remove and return the first element of the queue,if the queue is not empty. • peek()
– Return the element of the queue without removing it,if the queue is not empty. • size() – Return
the number of elements in the queue.

• isEmpty() – Return true if the queue is empty, otherwise returnfalse.


• isFull() – Return true if the queue is full, otherwise return false.

10
//Queue ADT Type Definitions

typedefstructnode {

void*DataPtr;

structnode *next;

} QueueNode;

typedefstruct {

QueueNode *front;

QueueNode *rear;

intcount;

Fig 6. Queue ADT


} QUEUE;

6.ARRAYS

The number of data items chunked together into a unit is known as data structure. When the data
structure consists simply a sequence of data items, the data structure of this simple variety is
referred as an array.
Definition: Array is a collection of homogenous (same data type) dataelements that are stored in
contiguous memory locations.

Array Syntax
Syntax to declare an array:
✱ dataType [ ] arrayName;
arrayName= new dataType[n]; //keyword new performs dynamicmemory location
(or)
✱ dataType [ ] arrayName = new dataType[n];

Example:
int [ ] x; x=new int [10];(or)
int [] x=new int [10];

11
Array Initialization
The values of an array can be initialized as follows,

Example 1:
int [] j=new int [1]; j[0] =10;(or)int [] j= {25};

Example 2:
int [] myarray= {5, 10};

5.1 Characteristics of an Array


The following are the characteristics of an array data structure.
(i) Array stores elements of same data type.
(ii) The elements of an array are stored in subsequent memorylocations.

(iii) The name of array represents the starting address of the elements.

(iv) When data objects are stored in array, individual objects areselected by an index. (v) By
default an array index starts from 0 and ends with (n-1). Indexis also referred as subscripts.
(vi) The size of the array is mentioned at the time of declaring array.
(vii) While declaring 2D array, number of columns should be specifiedwhereas for
number of rows there is no such rule.
(viii) Size of array can’t be changed at run time.

5.2Array Types
1.One-Dimensional Array or Linear arrays

12
2. Multi-Dimensional Array
3.Two dimensional (2D) Arrays or Matrix Arrays

5.2.1 One-Dimensional Array


In one dimensional array each element is represented by a single subscript. The elements
are stored in consecutive memory locations. E.g.A [1], A [2], ......., A [N]. 5.2.2 Two
dimensional (2-D) arrays or Matrix Arrays

In two dimensional arrays each element is represented by two subscripts. Thus a two
dimensional m x n array has m rows and n columns and contains m * n elements. It is also
called matrix array because in this case, the elements form a matrix. For example A [4] [3]has
4 rows and 3 columns and 4*3 = 12 elements.

int [] [] A = new int [4] [3];


5.2.3 Multi dimensional arrays:
In it each element is represented by three subscripts. Thus a three dimensional m x n x l array
contains m * n * l elements. For exampleA [2] [4] [3] has 2 * 4 * 3 = 24 elements.

6.STORAGE REPRESENTATION
An array is a set of homogeneous elements. Every element is referredby an index. Memory
storage locations of the elements are not arrangedas a rectangular array with rows and columns.
Instead, they are arranged in a linear sequence beginning with location 1, 2, 3 and so on. The
elements are stored either column-by-column or row-by-row. The first one is called column-major
order and later is referred as row-major order.
13
6.1 Row Major Order

The table 1 shows the linear arrangement of data in row major order.

Example

• Rows : 3
• Columns : 4

Data (A):

1234
5678
9 10 11 12

Table 1 Linear Arrangement of Array A in Row Major Order


Linear Arrangement of Array A

Row 1 2 3

Index (1,1 ) (1,2 (1,3 (1,4 (2,1 (2,2 (3,1 (3,2 (3,3 (3,4
) ) ) ) (2,3 ) ) ) )
(2,4
)
)
)
Memor 102 104 106 108 110 112 114 116 118 120 122
100
y

Data 1 2 3 4 5 678 9 10 11 12

The formula is:


Location (A [j,k] ) = Base Address of (A) + w [ (N * (j-1)) + (k-1) ]
Location (A [j, k] ): Location of jthrow and kth column

Base (A) : Base Address of the Array A

w : Bytes required to represent single element of the Array A

14
N : Number of columns in the Array

j : Row position of the element

k : Column position of the element

Example

Suppose to find the address of (3,2) then

Base (A) = 100

w = 2 Bytes (integer type)

N=4

j=3

k=2

Location ( A [3, 2] ) = 100 + 2 [ (4 * (3-1) + (2-1) ]

= 118

6.2 Column Major Order


The table 2 shows the linear arrangement of data in column major order.
• Rows : 3
• Columns : 4

Data (A):

1234

5678

9 10 11 12

15
Linear Arrangement of Array A

Colum 23 4
1
n

Index (1,1 ) (2,1 (3,1 (1,2 (2,2 (3,2 (3,3 (1,4 (2,4 (3,4
) ) ) ) (1,3 ) ) ) )
(2,3
)
)
)

Memor y 122
100 102 104 106 108 110 112 114 116 118 120

Data 1 5 9 2 6 10 3 7 11 4 8 12
Table 2 Linear Arrangement of Array A in Column Major Order
The formula for column major order is:
Location (A [j, k] ) = Base Address of (A) + w [ (M * (k-1)) + (j-1) ]

Location (A [j, k] ): Location of jthrow and kth column

Base (A) : Base Address of the Array A

w : Bytes required to represent single element of the Array A M : Number of

rows in the Array

j : Row position of the element

k : Column position of the element

Example

Base (A) = 100


w = 2 Bytes (integer type)
M=3
j=3
k=2

16
Location ( A [3, 2] ) = 100 + 2 [ (3 * (2-1) + (3-1) ]
= 110

7.Array Order Reversal


Given an array (or string), the task is to reverse the array/string.

Examples:
Input : arr[] = {1, 2, 3} Output : arr[] = {3, 2, 1} Input : arr[] = {4, 5,
1, 2} Output : arr[] = {2, 1, 5, 4}
Algorithm
1) Initialize start and end indexes as start = 0, end = n-1.
2) In a loop, swap arr[start] with arr[end] and change start and end as follows : start =
start +1, end = end – 1
8.Array Counting
1. Create a function arraycounting(array, size)

2. Find largest element in array and store it in max

3. Initialize count array with all zeros

4. for j = 0 to size

5. Find the total count of each unique element and

6. Store the count at jth index in count array

17
Example A={4,2,2,8,3,3,1}

1. Find out the maximum element (let it be max) from the given array.

2. Initialize an array of length max+1 with all elements 0. This arrayis used for storing the
count of the elements in the array.
3. Store the
count of each element at their respective index in count array. For example: If
the count of
th position in the
element “4” occurs 2 times then2 is stored in the 4 count array. If element

“5” isnot present in the array, then 0 is stored in 5th

8. Finding the maximum Number in a Set


Algorithm
✱ Read the array elements

✱ Initialize first element of the array as max.

✱ Traverse array elements from second and compare every elementwith current max ✱
Find the largest element in the array and assign it as max

✱ Print the largest element.

Example: A={56,78,34,23,70}

Step 1: Initialize max=0 , n=len(A)

18
Step 2: Repeat step 3 until n
Step 3: 56>0 yes, Assign max=56
78>56, yes Assign max=78
34>78, No
23>78, No
70>78, No
Step 4: print Max Output:78

9. RECURSION
Recursion is a programming technique using function or algorithm that calls itself one or more
times until a specified condition is met at which time the rest of each repetition is processed from
the last one calledto the first.

A simple recursive algorithm:


✱ Solves the base cases directly.

✱ Recurs with a simpler sub problem or sub problems.

✱ May do some extra work to convert the solution to the simpler subproblem into a solution to
the given problem.

Some Example Algorithms


• Factorial
• All permutations
• Tree traversal
• Binary Search
• Quick Sort
• Towers of Hanoi
9.1 Design Methodology and Implementation of Recursion

✱ The recursive solution for a problem involves a two-way journey:

✱ First we decompose the problem from the top to the bottom

✱ Then we solve the problem from the bottom to the top.


Rules for Designing a Recursive Algorithm
(a) First, determine the base case.
(b) Then determine the general case.

19
(c) Combine the base case and the general cases into an algorithm.
(d) Each recursive call must reduce the size of the problem and moveit toward the
base case.

(e) The base case, when reached, must terminate without a call to therecursive
algorithm; that is, it must execute a return.
9.2 Broad Categories of Recursion
Recursion is a technique that is useful for defining relationships, andfor designing algorithms
that implement those relationships. It is a natural way to express many algorithms in an optimized
way. Recursive function is defined in terms of itself.

✱ Linear Recursion

✱ Binary Recursion

Linear Recursion:
Linear recursion is by far the most common form of recursion. In this style of recursion, the
function calls itself repeatedly until it hits the termination condition (Base condition).

Binary Recursion
Binary recursion is another popular and powerful method. This formof recursion has the
potential for calling itself twice instead of once asbefore. This is pretty useful in scenarios such
as binary tree traversal,generating a Fibonacci sequence, etc.
Tail Recursion
A function call is said to be tail recursive if there is nothing to doafter the function returns except
return its value. Since the current recursive instance is done executing at that point, saving its
stack frameis a waste

For example the following C function print () is tail recursive.

// An example of tail recursive functionPrint (n) {


If (n < 0) return;
Display n;
Print (n-1);

20
10. FIBONACCI SERIES
Fibonacci Series generates subsequent number by adding two previous numbers. Fibonacci
series starts from two numbers F0 & F1. The initial values of F0 & F1 can be ✱ 0 and 1

✱ 1 and 1 respectively.

The Fibonacci series looks like


F8 = 0 1 1 2 3 5 8 13

The algorithm for generating Fibonacci series can be drafted in 2 ways

1. Fibonacci Iterative Algorithm.

2. Fibonacci Recursive Algorithm.

Fibonacci RecursiveAlgorithm

Algorithm Fibo (n)


If n = 0
Return 0Else If n = 1
Return 1
Else
Fibo (n) = Fibo (n-1) + Fibo (n-2)Return Fibo (n)

11.FACTORIAL
The factorial of a positive number is the product of the integral values from 1 to the number:
Factorial of the given number can be calculated as

Algorithm
RecursiveFactorial (n)if (N equals 0)
Return 1
else
Return (n*recursiveFactorial (n-1))
end if

21
end recursiveFactorial

Calling a Recursive Factorial Algorithm with n=3

Fig.6 shows the steps for calculating the factorial using Recursion for n=3.
Fig 6. Factorial using Recursion Steps
Output: 6
12. TOWERS OF HANOI
Tower of Hanoi is a mathematical puzzle which consists of three tower (pegs) and more than
one ring; as depicted in Fig.7.

Towers

Disks

Smallest
Largest

Fig.7 Tower of Hanoi


These rings are of different sizes and stacked upon in ascending order i.e. the smaller one sits over
the larger one. There are other variationsof puzzle where the number of disks increases, but the
tower count remains the same.

7.1 Rules
The mission is to move all the disks to some another tower without violating the sequence of
arrangement. The below mentioned are few rules which are to be followed for Tower of Hanoi

22
✱ Only one disk can be moved among the towers at any given time. ✱

Only the “top” disk can be removed.


✱ No large disk can sit over a small disk.

Steps for solving the Towers of Hanoi problem


The following steps are to be followed.
Step 1: Move n-1 disks from source to aux.
Step 2: Move nth disk from source to destination
Step 3: Move n-1 disks from aux to destination.
F i g . 8 illustrates the step by step movement of the disks to implement Tower of Hanoi.

Step: 0
Step: 2

23
Step: 6
24

Done! Fig.8
Tower of Hanoi
A recursive algorithm for Tower of Hanoi can be driven as followsSTART
Procedure Hanoi (disk, source, dest, aux)
IF disk = 0, THEN
Move disk from source to destELSE
Hanoi (disk-1, source, aux, dest) //Step1Move disk from source to dest //Step2 Hanoi (disk-1,
aux, dest, source) //Step3 ENDIF
END
25
SCHOOL OF COMPUTING
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
UNIT – II-Data Structures – SCSA1205

26
UNIT 2
LINKED LIST

Array Vs Linked List – Singly linked list - Representation of a linked list in memory -
Operations on a singly linked list - Merging two singly linked lists into one list - Reversing a
singly linked list – Polynomial Manipulation using List - Advantages and disadvantages of
singly linked list - Circular linked list - Doubly linked list - Circular Doubly Linked List.
2.1 Array Vs Linked List
ARRAY LINKED LIST
Array is a collection of elements Linked List is an ordered collection of elements
of similar data type. of same type, which are connected to each other
using pointers.

Array supports Random Access, Linked List supports Sequential Access, which
which means elements can be means to access any element/node in a linked
accessed directly using their index. list, we have to sequentially traverse the
complete linked list, up to that element.

In an array, elements are stored in In a linked list, new elements can be stored
contiguous memory location or anywhere in the memory. Address of the
consecutive manner in the memory. memory location allocated to the new element
is stored in the previous node of linked list,
hence forming a link between the two
nodes/elements.
In array, Insertion and Deletion
operation takes more time, as the In case of linked list, a new element is stored at
memory locations are consecutive and the first free and available memory location,
fixed. with only a single overhead step of storing the
address of memory location in the previous
node of linked list.Insertion and Deletion
operations are fast in linked list.

27
Memory is allocated as soon as the Memory is allocated at runtime, as and when a
array is declared, at compile time. It's new node is added. It's also known as Dynamic
also known as Static Memory Memory Allocation.
Allocation.

ARRAY LINKED LIST

In array, each element is In case of a linked list, each node/element


independent and can be accessed points to the next, previous, or maybe both
using it's index value. nodes.

Array can be single dimensional, Linked list can be Linear(Singly) linked list,
two dimensional or Doubly linked list or Circular linked list linked
multidimensional. list.

Size of the array must be specified Size of a Linked list is variable. It grows
at time of array declaration. at runtime, as more nodes are added to
it.

Array gets memory allocated in the Stack Whereas, linked list gets memory allocated in
section. Heap section.
2.2 Linked List
A Linked list is a collection of elements called nodes, each of which stores two items called
data or info and link or pointer field. Info is an element of the list and a link is a pointer to the next
element. The linked list is also called a chain.
The different types of Linked lists are,

• Singly linked list.


• Doubly linked list
• Circular linked list

Singly Linked List

• The first node is the head node and it points to next node in the sequence.
• The last node’s reference is null indicating the end of the list is shown in Fig.2.1

Fig.2.1 Singly Linked List

Doubly Linked List

28
• Every node has two pointers, one for pointing to next node and the other for pointing to the
previous node.
• The next pointer of the last node and the previous pointer of the first node (head) are null is shown
in Fig 2.2

Fig.2.2 Doubly Linked List


Circular Linked List

• CircularLinked List is very similar to a singly linked list except that, here the last node points to
the first node making it a circular list as shown in fig 2.3
Fig.2.3 Circular Linked List

2.2.1 Singly Linked List


A singly linked list is a linked list in which each node contains only one link pointing to the
next node in the list.
A Node in a linked list holds the data value and the pointer which points to the location of
the next node in the linked list.

2.2.1.1 Representation of a linked list in memory


A linked list is a linear data structure consisting of a group of nodes where each node points
to the next node by means of a pointer.
Each node is composed of data and a reference to the next node in the sequence. The last node
has a reference to null which indicates the end of the linked list.

Head node is the starting node of the linked list(first node) and it contains the reference to the next
node in the list. The head node will have a null reference when the list is empty. The fig 2.4 gives
you an idea of how a Linked List looks.

29
A linked list is represented by a pointer to the first node of the linked list. The first node is called
the head. If the linked list is empty, then the value of the head is NULL. In C, we can represent a
node using structures.
Fig 2.4 Singly Linked List representation
In the picture above we have a linked list, containing 4 nodes, each node has some data(A, B, C
and D) and a pointer which stores the location of the next node.

In a singly linked list, the first node always pointed by a pointer called HEAD. If the link of the
node points to NULL, then that indicates the end of the list.

Operations of Singly Linked List


The operations that are performed on a linear list are,

• Count the number of elements.


• Add an element at the beginning of the list.
• Add an element at the end of the list.
• Insert an element at the specified position in the list.
• Delete an element from the list.
• Search x in the list.
• Display all the elements of the list.

Add an element at the beginning of the list.

Step 1 - Create a newNode with given value.

Step 2 - Check whether list is Empty (head == NULL)

Step 3 - If it is Empty then, set newNode→next = NULL and head = newNode.

Step 4 - If it is Not Empty then, set newNode→next = head and head =

newNode.
30
Algorithm

Addatbeg()
Begin

Newnode->data=K

Newnode->next=NULL

If(Head==NULL)

Head=Newnode

Else

Newnode->next=Head

Head=Newnode

Endif

End

The fig.2.5 shows how a node is added at the beginning of the linked list.

Fig 2.5
Adding node at the beginning of the linked list

Add an element at the end of the list.

Step 1 - Create a newNode with given value and newNode → next as NULL.
31
Step 2 - Check whether list is Empty (head == NULL).

Step 3 - If it is Empty then, set head = newNode.


Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.

Step 5 - Keep moving the temp to its next node until it reaches to the last node in the
list (until temp → next is equal to NULL).

Step 6 - Set temp → next = newNode.

Algorithm

Addatend()

Begin

Newnode->data=K

Newnode->next=NULL

If(Head==NULL)

Head=Newnode

Else

Temp=Head

While(temp->next !=NULL)

temp=temp->next

endwhile

temp->next=Newnode

Endif

end

The Fig 2.6 shows how the node is added at the end of the list.
32
Fig 2.6 Node added at the end of the list
Insert an element at the specified position in the list:

Step 1 - Create a newNode with given value.

Step 2 - Check whether list is Empty (head == NULL)

Step 3 - If it is Empty then, set newNode → next = NULL and head = newNode.

Step 4 - If it is Not Empty then, define a node pointer temp and initialize with

head.

Step 5 - Keep moving the temp to its next node until it reaches to the node after which we
want to insert the newNode (until temp1 → data is equal to location, here location is the
node value after which we want to insert the newNode).

Step 6 - Every time check whether temp is reached to last node or not. If it is reached to last
node then display 'Given node is not found in the list!!! Insertion not possible!!!' and
terminate the function. Otherwise move the temp to next node.

Step 7 - Finally, Set 'newNode → next = temp → next' and 'temp → next = newNode'
33
The operation ‘Insert’ inserts the given element x in the kth position. A temporary pointer Temp is
created and made to point to Head. Now the Temp pointer is moved to the k – 1th node. A new node
with value x is created and the link of the new node is made to point to the position where the link
of temp is pointing. Then the link of temp is made to point to the new node. Thus the given element
is inserted in the position k is shown in fig.2.7.
Fig 2.7 Inserting node at position

Algorithm
Function insertin_mid()
Begin
Write "Enter the position:"
Read pos;
If head==NULL AND pos=1
then
Insert the node at the beginning
End if
If head->next==NULL AND pos=2
then
insert the node
End if
Else if pos>=2 AND pos<=ct

34
then
prev=head
for I = 2 to pos - 1 step +1
do
prev=prev->link
END FOR
next=prev->link
temp=new node
Write”Enter the data:"
Read temp->data
temp->link=next
prev->link=temp
ct=ct+1
else
Write "Enter a valid position & try again"
End if
End

Deletion
In a single linked list, the deletion operation can be performed in three ways. They are as follows...

• Deleting from Beginning of the list


• Deleting from End of the list
• Deleting a Specific Node

Deleting from Beginning of the list

We can use the following steps to delete a node from beginning of the single linked list...

Step 1 - Check whether list is Empty (head == NULL)

Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminate the function.

Step 3 - If it is Not Empty then, define a Node pointer 'temp' and initialize with head.

Step 4 - Check whether list is having only one node (temp → next == NULL)

Step 5 - If it is TRUE then set head = NULL and delete temp (Setting Empty list
conditions)
Step 6 - If it is FALSE then set head = temp → next, and delete temp.

Deleting from End of the list


We can use the following steps to delete a node from end of the single linked list...

Step 1 - Check whether list is Empty (head == NULL)

35
Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminate the function.
Step 3 - If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and
initialize 'temp1' with head.

Step 4 - Check whether list has only one Node (temp1 → next == NULL)

Step 5 - If it is TRUE. Then, set head = NULL and delete temp1. And terminate the
function. (Setting Empty list condition)

Step 6 - If it is FALSE. Then, set 'temp2 = temp1 ' and move temp1 to its next node.
Repeat the same until it reaches to the last node in the list. (until temp1 → next ==
NULL)

Step 7 - Finally, Set temp2 → next = NULL and delete temp1.

Deleting a Specific Node from the list

We can use the following steps to delete a specific node from the single linked list...

Step 1 - Check whether list is Empty (head == NULL)

Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminate the function.

Step 3 - If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and
initialize 'temp1' with head.

Step 4 - Keep moving the temp1 until it reaches to the exact node to be deleted or to the
last node. And every time set 'temp2 = temp1' before moving the 'temp1' to its next node.

Step 5 - If it is reached to the last node then display 'Given node not found in the list!
Deletion not possible!!!'. And terminate the function.

Step 6 - If it is reached to the exact node which we want to delete, then check whether list is
having only one node or not

Step 7 - If list has only one node and that is the node to be deleted, then set head = NULL
and delete temp1 (free(temp1)).
Step 8 - If list contains multiple nodes, then check whether temp1 is the first node in the list
(temp1 == head).

Step 9 - If temp1 is the first node then move the head to the next node (head = head →
next) and delete temp1.

Step 10 - If temp1 is not first node then check whether it is last node in the list (temp1 →
next == NULL).

36
Step 11 - If temp1 is last node then set temp2 → next = NULL and delete temp1
(free(temp1)).

Step 12 - If temp1 is not first node and not last node then set temp2 → next = temp1 →
next and delete temp1 (free(temp1)).

Algorithm

Function del()
Begin
if(head= NULL)
then
Write “Empty list"
else
Write “Enter the position:"
Read pos
if(pos==1)
then
next=head->link
head=next
ct=ct-1
else
if((pos>=2)&&(pos<=ct))
prev=head
for(int i=2;i<=pos-1;i++)
Do
prev=prev->link
End FOR
temp=prev->link
next=temp->link
prev->link=next
ct=ct-1
End if
End If
End

Displaying a Single Linked List


We can use the following steps to display the elements of a single linked list...

Step 1 - Check whether list is Empty (head == NULL)

Step 2 - If it is Empty then, display 'List is Empty!!!' and terminate the function.

Step 3 - If it is Not Empty then, define a Node pointer 'temp' and initialize with head.

Step 4 - Keep displaying temp → data with an arrow (--->) until temp reaches to the
last node
37
Step 5 - Finally display temp → data with arrow pointing to NULL (temp → data --->
NULL).

Counting

count()
begin
int co=0;
do
co++;
c=c->link;
while(c!=NULL);
return co;
end

Searching

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

Algorithm
Function search()
Begin
flag=0
if(head=NULL)
then
Write “Empty list"
else
Write ”Enter the element to be searched:"
Read e
cur=head
FOR I = 1 to ct Step +1
Do
if(cur->data= e)
then

pos=I
flag++
break
else

cur=cur->link
End if
ENDFOR
If (flag =1)

38
then
Write "Element found in position:" pos

else

Write ”Element not found"


End if

End Search

2.3 Merging

Node* MergeLists(Node* list1, Node* list2)


begin
Node* mergedList;
if(list1 == null && list2 ==null)
return null;
if(list1 == null)
return list2;

if(list2 == null){
return list1;
}
if(list1.data < list2.data){//initialize mergedList pointer to list1 if list1's data is lesser
mergedList = list1;
}else{//initialize mergedList pointer to list2 if list2's data is lesser or equal
mergedList = list2;
}
while(list1!=null && list2!=null){
if(list1.data < list2.data){
mergedList->next = list1;
list1 = list1->next;
}else{
mergedList->next = list2;
list2 = list2->next;
}
}
if(list1 == null){//remaining nodes of list2 appended to mergedList when list1 has
reached its end.
mergedList->next = list2;
}else{//remaining nodes of list1 appended to mergedList when list2 has reached its end
mergedList->next = list1;
}
return mergedList;
}

39
Traversing

The operation Display( ), displays all the value in each node of the list. A temporary pointer is
created and made to point to Head initially. Now info part of Temp is printed and Temp is moved to
the next node. This is repeated till the end of the list is reached.
Algorithm
Function display()
Begin
cur=head
cout<<"\nNo.of nodes is:"<<ct
cout<<"\nThe data is:"
while (cur< >NULL)
Do
Write "["<<cur->data<<"]->"
cur=cur->link
End while
End

2.4 Reverse the Linked List


Algorithm
reverse()
{
struct node *p1,*p2,*p3;
if(start->link==NULL)
return;
p1=start;
p2=p1->link;
p3=p2->link;
p1->link=NULL;
p2->link=p1;
while(p3!=NULL)
{
p1=p2;
p2=p3;
p3=p3->link;
p2->link=p1;
}
start=p2;
}

40
2.5 Polynomial Manipulation using List
5x2 + 3x1 + 1
12x3– 4x1
5x4– 8x3 + 2x2 + 4x1 + 9x0
It is not necessary to write terms of the polynomials in decreasing order of degree. In other words
the two polynomials 1 + x and x + 1 are equivalent.
The computer implementation requires implementing polynomials as a list of pairs of coefficient
and exponent. Each of these pairs will constitute a structure, so a polynomial will be represented as
a list of structures. A linked list structure that represents polynomials 5x4 – 8x3 + 2x2 + 4x1 + 9x0
illustrates in fig 2.8

Fig2.8 Polynomial Manipulation


Algorithm
node * getnode()
{
node *tmp;
tmp =(node *) malloc( sizeof(node) );
printf("\n Enter Coefficient : ");
fflush(stdin);
scanf("%f",&tmp->coef);
printf("\n Enter Exponent : ");
fflush(stdin);
scanf("%d",&tmp->expo);
tmp->next = NULL;
return tmp;
}
node * create_poly (node *p )
{
char ch;
node *temp,*newnode;
while( 1 )
{
printf ("\n Do U Want polynomial node (y/n): ");
ch = getche();
if(ch == 'n')
break;
newnode = getnode();
if( p == NULL )
p= newnode;
else

41
{
temp = p;
while(temp->next != NULL )
temp = temp->next;
temp->next = newnode;
}
}
return p;
}
void display (node *p)
{
node *t = p;
while (t != NULL)
{
printf("+ %.2f", t -> coef);
printf("X^ %d", t -> expo);
t=t -> next;
}
}

2.6 Advantages and disadvantages of singly linked list

Advantages of Singly Linked List

• it is very easier for the accessibility of a node in the forward direction. •

the insertion and deletion of a node are very easy.


• the Requirement will less memory when compared to doubly, circular or doubly
circular linked list.

• the Singly linked list is the very easy data structure to implement.

• During the execution, we can allocate or deallocate memory easily.

• Insertion and deletion of elements don’t need the movement of all the elements when
compared to an array.

Disadvantages of Singly Linked List

• therefore, Accessing the preceding node of a current node is not possible as there is no
backward traversal.

• the Accessing of a node is very time-consuming.

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

Fig 2.9 Circular Linked List

The basic operations in a circular single linked list are:


• Creation.
• Insertion.
• Deletion.
• Traversing.
Creating a circular single Linked List with ‘n’ number of nodes:
The following steps are to be followed to create ‘n’ number of nodes:
• Get the new node using getnode().
newnode = getnode();
• If the list is empty, assign new node as start.
start = newnode;
• If the list is not empty, follow the steps given below:
temp = start;
while(temp -> next != NULL)
temp = temp -> next;
temp -> next = newnode;
• Repeat the above steps ‘n’ times.
• newnode -> next = start;
Inserting a node at the beginning:
The following steps are to be followed to insert a new node at the beginning of
the circular list:
• Get the new node using getnode().
newnode = getnode();
• If the list is empty, assign new node as start.
start = newnode;

43
newnode -> next = start;
• If the list is not empty, follow the steps given below:
last = start;
while(last -> next != start)
last= last -> next;
newnode -> next = start;
start = newnode;
last -> next = start;
The function cll_insert_beg(), is used for inserting a node at the beginning. Figure shows inserting a
node into the circular single linked list at the beginning.
Fig 2.10 Inserting a node at the beginning
Inserting a node at the end:
The following steps are followed to insert a new node at the end of the list:
• Get the new node using getnode().
newnode = getnode();
• If the list is empty, assign new node as start.
start = newnode;
newnode -> next = start;
• If the list is not empty follow the steps given below:
temp = start;
while(temp -> next != start)
temp = temp -> next;
temp -> next = newnode;
newnode -> next = start;
The function cll_insert_end(), is used for inserting a node at the end.
Fig 2.11 shows inserting a node into the circular single linked list at the end.

44

Fig.2.11 Inserting node at the end

Deleting a node at the beginning:


The following steps are followed, to delete a node at the beginning of the
list: • If the list is empty, display a message ‘Empty List’.
• If the list is not empty, follow the steps given below:
last = temp = start;
while(last -> next != start)
last= last -> next;
start = start -> next;
last -> next = start;
• After deleting the node, if the list is empty then start = NULL.
The function cll_delete_beg(), is used for deleting the first node in the list. Fig
2.12 shows deleting a node at the beginning of a circular single linked list.

Fig 2.12 Deleting a node at the beginning

Deleting a node at the end:


The following steps are followed to delete a node at the end of the list:
• If the list is empty, display a message ‘Empty List’.
• If the list is not empty, follow the steps given below:
temp = start;
prev = start;
while(temp -> next != start)
{
prev=temp;
temp = temp -> next;
}
prev -> next = start;
• After deleting the node, if the list is empty then start = NULL.
The function cll_delete_last(), is used for deleting the last node in the list.Fig 2.13 shows deleting a
node at the end of a circular single linked list.

45

2.13 Deleting the node at the end

Traversing a circular single linked list from left to right:

The following steps are followed, to traverse a list from left to right:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
do
{
printf("%d", temp -> data);
temp = temp -> next;
} while(temp != start);

2.7 Doubly linked list


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

In a doubly linked list, the head always points to the first node. The prev pointer of the first
node points to NULL and the next pointer of the last node points to NULL shown in Fig.2.14

Operations on a Doubly linked list are,

• Count the number of elements.


• Add an element at the beginning of the list.
• Add an element at the end of the list.
• Insert an element at the specified position in the list.
• Delete an element from the list.
• Display all the elements of the list.

46
Addatbeg(x)
The operation Addatbeg(x) adds a given element x at the beginning of the list. A new node
R is created and the value x is store in the data part of R. The prev pointer of R is made to point to
NULL and the next pointer is made to point to head. Then the prev pointer of head is made to point
to R and head is now moved to point to R making it the first node. Thus the new node is added at
the beginning of the doubly linked list.

Algorithm
Function create()
Begin
temp=new node
Write"Enter the data:"
Read temp->data
End

Function insert_begin()
Begin
Call create()
tmp->flink=head
head=tmp
head->blink=NULL
ct=ct+1
End
Addatend(x)
The Addatend(x) operation adds the given element x at the end of the doubly linked list. If
the given list is empty then create a new node R and store the value of x in the data part of R. Now
make the prev pointer and the next pointer of R point to NULL. Then head is pointed to R. If the list
already contains some elements then, a temporary pointer is created and made to point to head. The
temp pointer is now moved to the last node and then a new node R is created. The value x is stored
in the data part of R and next pointer of R is made to point to NULL. The prev pointer of R is made
to point to temp and next pointer of Temp is made to point to R. Thus the new node is added at the
end of the doubly linked list is shown in fig.2.15.

Algorithm
Function append()
Begin
if(head=NULL)
then

insert_begin()
else
create()

47
temp->flink=NULL
prev=head
while(prev->flink< >NULL)
Do
prev=prev->flink
End while
prev->flink=temp
temp->blink=prev
ct=ct+1
End if
End
Fig. 2.15 Add at end

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

48
Write "Enter the position:"
Read pos;
If head->flink=NULL AND pos=1
then
Call insert_begin()
End if
If head->flink==NULL AND pos=2
then
Call append()
End if
Else if pos>=2 AND pos<=ct
then
prev=head
for I = 2 to pos - 1 step +1
do
prev=prev->flink
END FOR
next=prev->link
temp=new node
Write”Enter the data:"
Read temp->data
temp->flink=next
prev->flink=temp
temp->blink=prev;
next->blink=temp;
ct=ct+1
else
Write "Enter a valid position & try again"
End if
End

Fig.2.16 Insert at mid

49
Delete(x)

The Delete(x) operation deletes the element x from the doubly linked list. A temporary
pointer is created and made to point to head. Now the data of temp is compared with x and if it
matches that is the node to be deleted otherwise move to the next node and again compare. If the
node to be deleted is first node, then prev(next(temp)) is made to point to NULL and head is
pointed to next(temp). The node pointed by temp is deleted. When the node to be deleted is not the
first node, then next(prev(temp)) is made to point to next(temp) and prev(next(temp)) is made to
point to prev(temp). The node pointed by temp is deleted is shown in Fig.2.17.

Algorithm
Function del()
Begin
if(head= NULL)
then
cout<<"Empty list"
else
Write Enter the position\n"
Read pos
pre=head
if(pos<1 OR pos>ct)
Write Enter a valid position"
else
if(pos==1)
then
pre=pre->flink
head=pre
Write "node gets deleted\n"
Ct=ct -1
else
for(i=2;i<pos;i++)
pre=pre->flink
End For
tmp=pre->flink
nxt=tmp->flink
pre->flink=nxt
nxt->blink=pre
Write”node gets deleted\n"
Ct=ct -1
End if
End if

50
Fig.2.17 Deletion

2.8 Circular Doubly Linked List.


A circular double linked list has both successor pointer and predecessor pointer in circular
manner. The objective behind considering circular double linked list is to simplify the insertion and
deletion operations performed on double linked list. In circular double linked list the right link of
the right most node points back to the start node and left link of the first node points to the last
node. A circular double linked list is shown in fig 2.18.

Fig 2.18 Circular Doubly Linked List


The basic operations in a circular double linked list are:
• Creation.
• Insertion.
51
• Deletion.
• Traversing.

Create node
create_node(int info)
begin
new->val = info;
new->next = NULL;
new->prev = NULL;
return new;
end

Add Node at the end


Procedure add_node()
begin
Read info
if (first == last && first == NULL) // If list is empty
begin
first = last = new;
first->next = last->next = NULL;
first->prev = last->prev = NULL;
endif
Else // add the new node at the end
begin
last->next = new;
new->prev = last;
last = new;
last->next = first;
first->prev = last;
end
end
INSERTS ELEMENT AT FIRST

insert_at_first()
begin
Read info
new = create_node(info); // create the new node if (first
== last && first == NULL) // if the list is empty begin
first = last = new;
first->next = last->next = NULL;
first->prev = last->prev = NULL;
end
else
begin
52
new->next = first;
first->prev = new;
first = new;
first->prev = last;
last->next = first;
end
end

INSERTS ELEMNET AT END

insert_at_end()
begin
Read info;
new = create_node(info);
if (first == last && first == NULL)
begin
first = last = new;
first->next = last->next = NULL;
first->prev = last->prev = NULL;
endif
else
begin
last->next = new;
new->prev = last;
last = new;
first->prev = last;
last->next = first;
endif
end

INSERTS THE ELEMENT AT GIVEN POSITION

insert_at_position()
begin
Declare info, pos, len = 0, i;
Node *prevnode;
Read info and pos
new = create_node(info);
if (first == last && first == NULL)
begin
if (pos == 1)
begin
first = last = new;
first->next = last->next = NULL;
first->prev = last->prev = NULL;
endif
else

53
printf " empty linked list you cant insert at that particular position" endif
else
begin
if (number < pos) // total number of node is stored in the variable number print
“ node cant be inserted as position is exceeding the linkedlist length" else

for (ptr = first, i = 1;i <= number;i++)


begin
prevnode = ptr;
ptr = ptr->next;
if (i == pos-1)
begin
prevnode->next = new;
new->prev = prevnode;
new->next = ptr;
ptr->prev = new;
print "inserted at position is succesfully"
break;
end
end
end
end
end
Deletion
delete_node_position()
begin
int pos, count = 0, i;
n *temp, *prevnode;
read the position which u wanted to delete

if (first == last && first == NULL)


print " empty linked list you cant delete"
else
begin
if (number < pos)
print " node cant be deleted at position as it is exceeding the linkedlist length" else
begin
for (ptr = first,i = 1;i <= number;i++)
begin
prevnode = ptr;
ptr = ptr->next;
if (pos == 1)
begin

54
number--;
last->next = prevnode->next;
ptr->prev = prevnode->prev;
first = ptr;
printf("%d is deleted", prevnode->val);
free(prevnode);
break;
end
else if (i == pos - 1)
begin
number--;
prevnode->next = ptr->next;
ptr->next->prev = prevnode;
printf("%d is deleted", ptr->val); free(ptr);
break;
end
end
end
end
end

Searching

search()
begin
int count = 0, key, i, f = 0;
read the value to be searched in the variable key
if (first == last && first == NULL)
print "list is empty no elemnets in list to search"
else
for (ptr = first,i = 0;i < number;i++,ptr = ptr->next)
begin
count++;
if (ptr->val == key)
begin
Print " the value is found at position count ” f = 1;
end
end
if (f == 0)
print "the value is not found in linkedlist" end
end
55
DISPLAYING IN BEGINNING
Algorithm

display_from_beg()
begin
int i;
if (first == last && first == NULL)
print "list is empty no elemnts to print"
else
begin
Store total number of node in the variable , number for
(ptr = first, i = 0;i < number;i++,ptr = ptr->next) print
ptr->val
end
end
56

SCHOOL OF COMPUTING
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERIN
UNIT – III-Data Structures – SCSA1205

57
Unit:III
Introduction – Array Representation of a Stack – Linked List Representation of a Stack -
Stack Operations - Algorithm for Stack Operations - Stack Applications: Tower of Hanoi -
Infix to postfix Transformation - Evaluating Arithmetic Expressions. Queue – Introduction –
Array Representation of Queue – Linked List Representation of Queue - Queue Operations -
Algorithm for Queue Operations - . Queue Applications: Priority Queue.
3.1 Introduction

A stack is an Abstract Data Type (ADT), commonly used in most programming languages. It is
named stack as it behaves like a real-world stack, for example – a deck of cards or a pile of plates,
etc.
This feature makes it LIFO data structure. LIFO stands for Last-in-first-out. Here, the element
which is placed (inserted or added) last, is accessed first. In stack terminology, insertion operation is
called PUSH operation and removal operation is called POP operation.

Stack Representation
The following fig 3.1 depicts a stack and its operations −
Fig 3.1 Stack Representation
3.2 Array representation of a Stack

A stack can be implemented by means of Array, Structure, Pointer, and Linked List. Stack can
either be a fixed size one or it may have a sense of dynamic resizing. Here, we are going to
implement stack using arrays, which makes it a fixed size stack implementation. First we have to
allocate a

58
memory block of sufficient size to accommodate the full capacity of the stack. Then, starting from
the first location of the memory block, the items of the stack can be stored in a sequential fashion.

Fig 3.2 Representation of a stack


In Fig 3.2 a, Itemi denotes the ith item in the stack; l and u denote the index range of
the array in use; usually the values of these indices are 1 and SIZE respectively. TOP is a
pointer to point the position of the array up to which it is filled with the items of the stack.
3.3 Linked List Representation of Stacks

Although array representation of stacks is very easy and convenient but it allows the
representation of only fixed sized stacks. In several applications, the size of the stack may
vary during program execution. An obvious solution to this problem is to represent a stack
using a linked list. A single linked list structure is sufficient to represent any stack. Here,
the DATA field is for the ITEM, and the LINK field is, as usual, to point to the next' item.
Above Figure b depicts such a stack using a single linked list. In the linked list
representation, the first node on the list is the current item that is the item at the top of the
stack and the last node is the node containing the bottom-most item. Thus, a PUSH
operation will add a new node in the front and a POP operation will remove a node from
the front of the list is shown in Fig 3.2 b.

3.4 Stack Operations


Stack operations may involve initializing the stack, using it and then de-initializing it.
Apart from these basic stuffs, a stack is used for the following two primary operations −
• push() − Pushing (storing) an element on the stack.
• pop() − Removing (accessing) an element from the stack.

59
When data is PUSHed onto stack.
To use a stack efficiently, we need to check the status of stack as well. For the same purpose, the
following functionality is added to stacks −
• peek() − get the top data element of the stack, without removing it.
• isFull() − check if stack is full.
• isEmpty() − check if stack is empty.
At all times, we maintain a pointer to the last PUSHed data on the stack. As this pointer always
represents the top of the stack, hence named top. The top pointer provides top value of the stack
without actually removing it.
3.5 Algorithm for Stack Operations
Push Operation
The process of putting a new data element onto stack is known as a Push Operation is shown in
fig.3.3. Push operation involves a series of steps −
Step 1 − Checks if the stack is full.
Step 2 − If the stack is full, produces an error and exit.
Step 3 − If the stack is not full, increments top to point next empty space.
Step 4 − Adds data element to the stack location, where top is pointing.
Step 5 − Returns success.

Fig 3.3 Push Operation


If the linked list is used to implement the stack, then in step 3, we need to allocate space
dynamically. Algorithm for PUSH Operation

A simple algorithm for Push operation can be derived as follows −


procedure push

if stack is full
return null
endif
top ← top + 1
stack[top] ← data
end procedure

60
Pop Operation
Accessing the content while removing it from the stack, is known as a Pop Operation. In an array
implementation of pop() operation, the data element is not actually removed, instead top is
decremented to a lower position in the stack to point to the next value. But in linked-list
implementation, pop() actually removes data element and deallocates memory space is shown in
Fig.3.4.
A Pop operation may involve the following steps −
Step 1 − Checks if the stack is empty.
Step 2 − If the stack is empty, produces an error and exit.
Step 3 − If the stack is not empty, accesses the data element at which top is pointing.
Step 4 − Decreases the value of top by 1.

Step 5 − Returns success.


Fig 3.4 Pop Operation
Algorithm for Pop Operation
procedure pop: stack

if stack is empty
return null
endif
data ← stack[top]
top ← top - 1
return data
Displays the elements of a Stack
We can use the following steps to display the elements of a stack...

Step 1 - Check whether stack is EMPTY. (top == -1)

Step 2 - If it is EMPTY, then display "Stack is EMPTY!!!" and terminate the function.
Step 3 - If it is NOT EMPTY, then define a variable 'i' and initialize with top. Display stack[i]
value and decrement i value by one (i--).

Step 3 - Repeat above step until i value becomes '0'.

61
3.6 Stack Using Linked List
In linked list implementation of a stack, every new element is inserted as 'top' element. That
means every newly inserted element is pointed by 'top'. Whenever we want to remove an element
from the stack, simply remove the node which is pointed by 'top' by moving 'top' to its previous
node in the list. The next field of the first element must be always NULL.

Example
Fig 3.5 Linked List Representation
In the above Fig 3.5, the last inserted node is 99 and the first inserted node is 25. The order of
elements inserted is 25, 32,50 and 99.

Stack Operations using Linked List

push(value) - Inserting an element into the Stack

We can use the following steps to insert a new node into the stack...

Step 1 - Create a newNode with given value.

Step 2 - Check whether stack is Empty (top == NULL)

Step 3 - If it is Empty, then set newNode → next = NULL.

Step 4 - If it is Not Empty, then set newNode → next = top.

Step 5 - Finally, set top = newNode.


62
Algorithm

push(int value)

begin

newNode->data = value;
if(top == NULL)

newNode->next = NULL;

else

newNode->next = top;

top = newNode;

end

pop() - Deleting an Element from a Stack

We can use the following steps to delete a node from the stack...

Step 1 - Check whether stack is Empty (top == NULL).

Step 2 - If it is Empty, then display "Stack is Empty!!! Deletion is not


possible!!!" and terminate the function

Step 3 - If it is Not Empty, then define a Node pointer 'temp' and set it to

'top'. Step 4 - Then set 'top = top → next'.

Step 5 - Finally, delete 'temp'. (free(temp)).


63
Algorithm

void pop()

begin
if(top == NULL)

print("\nStack is Empty!!!\n");

else

print("\nDeleted element: %d", temp->data);

top = temp->next;

free(temp);

endif

end

display() - Displaying stack of elements

We can use the following steps to display the elements (nodes) of a stack...

Step 1 - Check whether stack is Empty (top == NULL).

Step 2 - If it is Empty, then display 'Stack is Empty!!!' and terminate the

function. Step 3 - If it is Not Empty, then define a Node pointer 'temp' and

initialize with top.


Step 4 - Display 'temp → data --->' and move it to the next node. Repeat the same until
temp reaches to the first node in the stack. (temp → next != NULL).

Step 5 - Finally! Display 'temp → data ---> NULL'.

64
Algorithm
void display()
begin
if(top == NULL)
print("\nStack is Empty!!!\n");
else{
struct Node *temp = top;
while(temp->next != NULL)
begin
print("%d--->",temp->data);
temp = temp -> next;
end
print("%d--->NULL",temp->data);
end

3.7 Stack Applications


3.7.1Tower of Hanoi
Tower of Hanoi is a mathematical puzzle which consists of three tower (pegs) and more than
one ring; as
depicted in
Fig.3.6.
Towers

Disks

Smallest

Largest

Fig.3.6 Tower of Hanoi


These rings are of different sizes and stacked upon in ascending order i.e. the smaller one sits over
the larger one. There are other variationsof puzzle where the number of disks increases, but the
tower count remains the same.
Rules
The mission is to move all the disks to some another tower without violating the sequence of

65
arrangement. The below mentioned are few rules which are to be followed for Tower of Hanoi •
Only one disk can be moved among the towers at any given time. • Only the “top” disk can be
removed.

• No large disk can sit over a small disk.

Steps for solving the Towers of Hanoi problem


The following steps are to be followed.
Step 1: Move n-1 disks from source to aux.
Step 2: Move nth disk from source to destination
Step 3: Move n-1 disks from aux to destination.
F i g . 3 . 7 , illustrates the step by step movement of the disks to implement Tower of Hanoi.
Step: 0

Step: 2
Fig 3.7 Tower of Hanoi

66
Step: 6Fig 3.7 Tower of Hanoi
67

Done! Fig.3.7 Tower of Hanoi


A recursive algorithm for Tower of Hanoi can be driven as followsSTART
Procedure Hanoi (disk, source, dest, aux)
IF disk = 0, THEN
Move disk from source to destELSE
Hanoi (disk-1, source, aux, dest) //Step1Move disk from source to dest //Step2 Hanoi
(disk-1, aux, dest, source) //Step3 ENDIF

END
3.7.2 Infix to postfix Transformation
There is an algorithm to convert an infix expression into a postfix expression. It uses a
stack; but in this case, the stack is used to hold operators rather than numbers. The purpose of the
stack is to reverse the order of the operators in the expression. It also serves as a storage structure,
since no operator can be printed until both of its operands have appeared.

In this algorithm, all operands are printed (or sent to output) when they are read. There are
more complicated rules to handle operators and parentheses.

Example:

1. A * B + C becomes A B * C +

The order in which the operators appear is not reversed. When the '+' is read, it has lower
precedence than the '*', so the '*' must be printed first.
We will show this in a table with three columns. The first will show the symbol currently being
read. The second will show what is on the stack and the third will show the current contents of the
postfix string. The stack will be written from left to right with the 'bottom' of the stack to the left.

68
current symbol operator stack postfix string

1AA

2**A

3B*AB

4 + + A B * {pop and print the '*' before pushing the '+'} 5 C + A B * C


6AB*C+

The rule used in lines 1, 3 and 5 is to print an operand when it is read. The rule for line 2 is to push
an operator onto the stack if it is empty. The rule for line 4 is if the operator on the top of the stack
has higher precedence than the one being read, pop and print the one on top and then push the new
operator on. The rule for line 6 is that when the end of the expression has been reached, pop the
operators on the stack one at a time and print them.

2. A + B * C becomes A B C * +
Here the order of the operators must be reversed. The stack is suitable for this, since operators will
be popped off in the reverse order from that in which they were pushed.

current symbol operator stack postfix string

1AA

2++A

3B+AB

4*+*AB
5C+*ABC

6ABC*+

In line 4, the '*' sign is pushed onto the stack because it has higher precedence than the '+' sign
which is already there. Then when the are both popped off in lines 6 and 7, their order will be
reversed.

69
3. A * (B + C) becomes A B C + *
A subexpression in parentheses must be done before the rest of the

expression. current symbol operator stack postfix string

1AA

2**A

3(*(AB
4B*(AB

5+*(+AB

6C*(+ABC

7)*ABC+

8ABC+*

Since expressions in parentheses must be done first, everything on the stack is saved and the left
parenthesis is pushed to provide a marker. When the next operator is read, the stack is treated as
though it were empty and the new operator (here the '+' sign) is pushed on. Then when the right
parenthesis is read, the stack is popped until the corresponding left parenthesis is found. Since
postfix expressions have no parentheses, the parentheses are not printed.

4. A - B + C becomes A B - C +
When operators have the same precedence, we must consider association. Left to right association
means that the operator on the stack must be done first, while right to left association means the
reverse.

current symbol operator stack postfix string


1AA

2--A

3B-AB

70
4++AB-

5C+AB-C

6AB-C+

In line 4, the '-' will be popped and printed before the '+' is pushed onto the stack. Both operators
have the same precedence level, so left to right association tells us to do the first one found before
the second.

5. A * B ^ C + D becomes A B C ^ * D +
Here both the exponentiation and the multiplication must be done before the

addition. current symbol operator stack postfix string

1AA

2**A

3B*AB

4^*^AB

5C*^ABC

6++ABC^*

7D+ABC^*D

8ABC^*D+

When the '+' is encountered in line 6, it is first compared to the '^' on top of the stack. Since it has
lower precedence, the '^' is popped and printed. But instead of pushing the '+' sign onto the stack
now, we must compare it with the new top of the stack, the '*'. Since the operator also has higher
precedence than the '+', it also must be popped and printed. Now the stack is empty, so the '+' can be
pushed onto the stack.

71
6. A * (B + C * D) + E becomes A B C D * + * E +

current symbol operator stack postfix string

1AA

2**A
3(*(A

4B*(AB

5+*(+AB

6C*(+ABC

7**(+*ABC

8D*(+*ABCD

9)*ABCD*+

10 + + A B C D * + *

11 E + A B C D * + * E

12 A B C D * + * E +

A summary of the rules follows:


1. Print operands as they arrive.
2. If the stack is empty or contains a left parenthesis on top, push the incoming operator
onto the stack.

3. If the incoming symbol is a left parenthesis, push it on the stack.


4. If the incoming symbol is a right parenthesis, pop the stack and print the operators until
you see a left parenthesis. Discard the pair of parentheses.
5. If the incoming symbol has higher precedence than the top of the stack, push it on the
stack.
6. If the incoming symbol has equal precedence with the top of the stack, use association. If
the association is left to right, pop and print the top of the stack and then push the incoming
operator. If the association is right to left, push the incoming operator.

72
7. If the incoming symbol has lower precedence than the symbol on the top of the stack, pop
the stack and print the top operator. Then test the incoming operator against the new top of
stack.
8. At the end of the expression, pop and print all operators on the stack. (No parentheses
should remain.)
Algorithm
int top = -1;
Infixtopostfix()
begin
print("\n\nRead the Infix Expression ? ");
Read infx
push('#');
while ((ch = infx[i++]) != '\0')
begin
if (ch == '(')
push(ch);
else if (isalnum(ch))
pofx[k++] = ch;
else if (ch == ')')
begin
while (s[top] != '(')
begin
pofx[k++] = pop();
elem = pop(); /* Remove ( */
end
else
while (pr(s[top]) >= pr(ch))
pofx[k++] = pop();
push(ch);
end
end

3.7.3 Evaluating Arithmetic Expressions


The stack organization is very effective in evaluating arithmetic expressions. Expressions are
usually represented in what is known as Infix notation, in which each operator is written between
two operands (i.e., A + B). With this notation, we must distinguish between ( A + B )*C and A + (
B * C ) by using either parentheses or some operator-precedence convention. Thus, the order of

73
operators and operands in an arithmetic expression does not uniquely determine the order in which
the operations are to be performed.

1. Polish notation (prefix notation) –


It refers to the notation in which the operator is placed before its two operands . Here no
parentheses are required, i.e., +AB
The procedure for getting the result is:
1. Convert the expression in Reverse Polish notation( post-fix notation).
2. Push the operands into the stack in the order they are appear.
3. When any operator encounter then pop two topmost operands for executing the operation.
4. After execution push the result obtained into the stack.

5. After the complete execution of expression the final result remains on the top of the stack.
For example –

Infix notation: (2+4) * (4+6)


Post-fix notation: 2 4 + 4 6 + *
Result: 60
6. The stack operations for this expression evaluation is shown below:
Fig 3.8 Arithmetic Expressions

3.8 Queue
3.8.1 Introduction
Queue is also an abstract data type or a linear data structure, just like stack data structure, in
which the first element is inserted from one end called the REAR(also called tail), and the removal

74
of existing element takes place from the other end called as FRONT (also called head). This makes
queue as FIFO (First in First Out) data structure, which means that element inserted first will be
removed first. The process to add an element into queue is called Enqueue and the process of
removal of an element from queue is called Dequeue.

3.8.2 Array Representation of Queue


If queue is implemented using arrays, the size of the array should be fixed maximum allowing the
queue to expand or shrink.
Operations on a Queue
There are two common operations one in a queue. They are addition of an element to the
queue and deletion of an element from the queue. Two variables front and rear are used to point to
the ends of the queue. The front points to the front end of the queue where deletion takes place and
rear points to the rear end of the queue, where the addition of elements takes place. Initially, when
the queue is full, the front and rear is equal to -1.
Add(x)
An element can be added to the queue only at the rear end of the queue. Before adding an
element in the queue, it is checked whether queue is full. If the queue is full, then addition cannot
take place. Otherwise, the element is added to the end of the list at the rear side.

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

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

DELQ( )

If front = -1

Then
Print “Queue is Empty”
Return
Else
Item = A[front]
A[front] = 0
If front = rear
Then
Front = rear = -1
Else
Front = front + 1

End if
Return item
End if
End DELQ( )

3.8.3 Linked List Representation of Queue

Queue can be represented using a linked list. Linked lists do not have any restrictions on the
number of elements it can hold. Space for the elements in a linked list is allocated dynamically;
hence it can grow as long as there is enough memory available for dynamic allocation. The queue
represented using linked list would be represented as shown. The front pointer points to the front of
the queue and rear pointer points to the rear of the queue is shown in Fig 3.9.

76

Fig 3.9 Linked List

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

ADDQ(x)
If front = NULL
Then
Rear = front = temp
Return

You might also like