0% found this document useful (0 votes)
10 views92 pages

BSC 3rdsem Course6 DS Using C

The document is a comprehensive guide on data structures using C, covering various topics such as Abstract Data Types (ADTs), algorithms, time and space complexity, and different types of data structures including arrays, linked lists, stacks, queues, trees, and graphs. It also includes explanations of searching and sorting techniques, along with their applications. The content is organized into units, each focusing on specific data structure concepts and operations.

Uploaded by

sudheerkuc.songs
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)
10 views92 pages

BSC 3rdsem Course6 DS Using C

The document is a comprehensive guide on data structures using C, covering various topics such as Abstract Data Types (ADTs), algorithms, time and space complexity, and different types of data structures including arrays, linked lists, stacks, queues, trees, and graphs. It also includes explanations of searching and sorting techniques, along with their applications. The content is organized into units, each focusing on specific data structure concepts and operations.

Uploaded by

sudheerkuc.songs
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
You are on page 1/ 92

1

DATA STRUCTURES USING C

UNIT-1
Introduction to Data Structures, Arrays

01. Write about ADTs (Abstract Data Types). - 03


02. Write differences between Data type & Data structure. - 04
03. What are the different types of data structures? [or]
Explain about primitive, non-primitive, linear & non-linear data structures. - 05
04. What is an algorithm? Write definition & characteristics of an algorithm. - 08
05. Write about time complexity & space complexity. - 09
06. Explain Big ‘O’ notation (or) Asymptotic notation. - 10
07. Arrays ADT – Operations, Types. - 11
08. Write about applications of two-dimensional arrays (Sparse Matrix). - 15
09. Write about Dynamic Memory Allocation in C. - 16

UNIT-2
Linked Lists

01. Write about single linked list & it’s operations. - 19


02. Write about doubly linked list & it’s operations. - 26
03. Write about circular linked list. - 30
04. Write differences between Array & Linked list. - 31
05. Write applications of linked lists. - 32

UNIT 3
Stacks & Queues

01. Stacks – ADT, Operations. - 33


02. Stacks – Arrays & Linked list representation. - 36
03. Write about Applications of stacks. (Infix to Postfix expression) - 40
04. Write about Recursion. Write differences between Recursion & Iteration. - 41
05. Queues – ADT, Operations. - 43
06. Queues – Arrays & Linked list representation. - 45
07. Write about ‘Circular Queues’. - 48
08. Write about ‘DEQUE’ (Double Ended Queues). - 49
09. Write about ‘Priority Queues’. - 50

Data Structures Using C | Sudheer Kumar Kasulanati


2

UNIT 4
Searching & Sorting

01. Linear [or] Sequential Search. - 51


02. Binary Search. - 52
03. Indexed Sequential Search. - 54
04. Bubble Sort. - 55
05. Insertion Sort. - 56
06. Selection Sort. - 58
07. Merge Sort. - 60
08. Quick Sort. - 62

UNIT 5
Trees & Graphs

01. Binary tree ADT – Types & Representation. - 65


02. Write about properties of Binary trees. - 70
03. Binary trees – Traversal techniques (In-order, Pre-order, Post-order). - 71
04. BST (Binary Search Tree) operations. - 73
05. Applications of Binary Trees [or] Threaded Binary Trees. - 77
06. Graphs – Representation. - 79
07. Graphs – Traversals (searching techniques) : DFS & BFS - 83
08. MST (Minimal Spanning Trees). - 85
09. Applications of Graphs [or] Connected components of Graphs. - 87

Model Paper 1 - 89

Model Paper 2 - 90

Data Structures Using C | Sudheer Kumar Kasulanati


3

UNIT 1
Introduction to Data Structures, Arrays

01. Write about ADTs (Abstract Data Types).

Abstract Data Type :


 Abstract Data Type deals with data along with operations, which can be performed on the
data.
 A data type can be considered abstract when it is defined in terms of operations on it, and its
implementation is hidden, so that we can always replace one implementation with another for
efficiency reasons.
 An ADT (sometimes called an abstract data type) is a mathematical model of a data structure.
It describes a container which holds a finite number of objects where the objects may be
associated through a given binary relationship.
 The operations which may be performed on the container may be basic (Ex. insert, remove etc.)
or may be based on the relationship (Ex. given an object find the next largest object).
 The definition of ADT only mentions what operations are to be performed but not how these
operations will be implemented.

 Following are some of the ADTs:

List ADT
Set ADT
Stack ADT
Queue ADT

 In List ADT, we have operations like insert(), delete(), search() etc.


 In Set ADT, we have operations like Union(), Intersection(), minus() etc.
 In Stack ADT, push() is used to insert element & pop() is used to delete element.
In Queue ADT, we have operations like Enqueue() to insert element & Dequeue() to delete
element.

Data Structures Using C | Sudheer Kumar Kasulanati


4

02. Write differences between Data type & Data structure.

Differences between Data type & Data structure:

 The most significant difference between a data type and a data structure is that a data type is the
representation of nature and type of data, whereas a data structure is a collection that holds different types
of data which can be manipulated and used in programming in an efficient manner.
 The following are some important differences between Data type & Data structure:

Key Data Type Data Structure

A data type represents the nature and Data structure is the collection that holds
type of data. All the data that belong data which can be manipulated and used in
to a common data type share some programming so that operations and
Definition common properties. algorithms can be more easily applied.
For example an integer data type For example, tree type data structures often
describes every integer that the allow for efficient searching algorithms.
computers can handle.

Data types are implemented in an Data structures are implemented in a


abstract manner. concrete manner.
Implementation
Their definitions are provided by Their definition includes what type of data
different languages in different ways. they are going to store and deal with.

Data types don't store the value of Data structures hold the data along with
data. their values.
Storage
They represent only the type of data Data structures can hold different types of
that is stored. data within one single object.

Data types represent the type of value In case of data structures, the data is
that can be stored, so values can assigned using some set of algorithms and
Assignment
directly be assigned to the data type operations like push, pop, enqueue,
variables. dequeue etc.

There is no issue of time complexity Time complexity plays an important role in


because data types deal only with the data structures because they deal with
Performance
type and nature of data. manipulation and execution of logic over
data that is stored.

Examples int, float, char, boolean etc. Stack, Queue, Tree, Graph etc.

Data Structures Using C | Sudheer Kumar Kasulanati


5

03. What are the different types of data structures? [or] Explain about primitive, non-
primitive, linear & non-linear data structures.

Data Structures:

 A data structure is a particular way of organizing data in a computer so that it can be used
efficiently.
 For example, we can store a list of items having the same data-type using an array.
 Below is the Array data structure.

 Data structure is about providing data elements in terms of some relationship for better organization.
 Data structure is just a container for the data that is used to store, manipulate and arrange. It can be
processed by algorithms.
 For example, while using a shopping website like Flipkart or Amazon, the users know their last orders and
can track them. The orders are stored in a database as records.
 When the program needs them so that it can display it to the user, it loads the data in some form of data
structure.

Types of Data Structures:

Data Structures Using C | Sudheer Kumar Kasulanati


6

Primitive Data Types:

 Primitive data types are the data types available in most of the programming languages.
 These data types are used to represent single value.
 It is a basic data type available in most of the programming language.

Data type Description

Integer Used to represent a number without decimal point.

Character Used to represent single character.

Real/Float Used to represent a number with decimal point.

Non-Primitive Data Types:


 Data type derived from primary data types are known as Non-Primitive data types.
 Non-Primitive data types are used to store group of values.
 It can be divided into two types:

1. Linear Data Structure


2. Non-Linear Data Structure

1. Linear Data Structure:


 Linear data structure traverses the data elements sequentially.
 In linear data structure, only one data element can directly be reached.
 It includes array, linked list, stack and queues.

Types Description
Arrays Array is a collection of elements. It is used in mathematical problems like matrix,
algebra etc. each element of an array is referenced by a subscripted variable or
value, called subscript or index enclosed in parenthesis.

Linked Linked list is a collection of data elements. It consists of two parts: Info and Link.
list Info gives information and Link is an address of next node. Linked list can be
implemented by using pointers.

Stack Stack is a list of elements. In stack, an element may be inserted or deleted at one
end which is known as Top of the stack. It performs two operations: Push and
Pop. Push means adding an element in stack and Pop means removing an element
in stack. It is also called Last-in-First-out (LIFO).

Queue Queue is a linear list of element. In queue, elements are added at one end called
rear and the existing elements are deleted from other end called front. It is also
called as First-in-First-out (FIFO).

Data Structures Using C | Sudheer Kumar Kasulanati


7

2. Non-Linear Data Structure

 Non-Linear data structure is opposite to linear data structure.


 In non-linear data structure, the data values are not arranged in order and a data item is
connected to several other data items.
 It uses memory efficiently. Free contiguous memory is not required for allocating data items.
 It includes trees and graphs.

Type Description
Tree Tree is a flexible, versatile and powerful non-linear data structure. It is used to
represent data items processing hierarchical relationship between the grandfather
and his children & grandchildren. It is an ideal data structure for representing
hierarchical data.

Graph Graph is a non-linear data structure which consists of a finite set of ordered pairs
called edges. Graph is a set of elements connected by edges. Each elements are
called a vertex and node.

Data Structures Using C | Sudheer Kumar Kasulanati


8

04. What is an algorithm? Write definition & characteristics of an Algorithm.

Algorithm:

 Algorithm refers to the sequence of instructions that must be followed to solve a problem.
 It is a logical representation of the instructions which should be executed to perform a task.
 An algorithm has some characteristics. These are follows;
 Each instruction should be unique.
 Each instruction should be relative in nature & should not be repeated infinitely.
 Repetition of same task should be avoided.
 The result should be available to the user after the algorithm terminates.
 After an algorithm has been designed, its efficiency must be analysed.
 This involves determining whether the algorithm is economical in the use of computer resources :
CPU time & Memory.
 Memory space is the memory required by an algorithm.
 Running time is the computational time required to execute the algorithm.

Characteristics of an Algorithm:

 Clear and Unambiguous:


The algorithm should be unambiguous. Each of its steps should be clear in all aspects and must lead to
only one meaning.
 Well-Defined Inputs:
If an algorithm says to take inputs, it should be well-defined inputs. It may or may not take input.
 Well-Defined Outputs:
The algorithm must produce atleast one output and it should be well defined.
 Finite-ness:
The algorithm must be finite, i.e. it should terminate after a finite amount of time.
 Feasible:
The algorithm must be simple and practical, such that it can be executed with the available resources.
It must not contain some future technology or anything.
 Language Independent:
The Algorithm designed must be language-independent, i.e. it must be just plain instructions that can be
implemented in any programming language and yet the output will be the same.

Data Structures Using C | Sudheer Kumar Kasulanati


9

05. Write about time complexity & space complexity.

Complexity (or) Computational complexity:

 Complexity is a characterization of the time or space requirements for solving a problem by a particular
algorithm.
 These requirements are expressed in terms of a single parameter that represents the size of the problem.
 The analysis of the program requires two main considerations:
 Time complexity
 Space complexity
 The time complexity is the amount of computer time that needs to execute the program.
 The space complexity is the amount of memory needs to execute the program.

Time Complexity:

 While measuring the time complexity of an algorithm, we concentrate on developing only the frequency
count for all basic instructions of an algorithm.
 This is because, it is often difficult to get reliable timing figure because of clock limitations and the
multiprogramming or the sharing environment.

 Consider the algorithm given below:

You are given an array A and an integer x and you have to find if x exists in array A. Simple solution to
this problem is traverse the whole array A and check if the any element is equal to x.

for i : 1 to length of A
if A[i] is equal to x
return TRUE
return FALSE

 Each of the operation in computer take approximately constant time. Let each operation takes c time. The
number of lines of code executed is actually depends on the value of x. During analysis of algorithm,
mostly we will consider worst case scenario, i.e., when x is not present in the array A. In the worst case,
the if condition will run N times where N is the length of the array A. So in the worst case, total execution
time will be (N*c + c). N*c for the if condition and c for the return statement.

Space Complexity:

 The space complexity of an algorithm or a computer program is the amount of memory space required to
solve an instance of the computational problem.
 It is the memory required by an algorithm until it executes completely.
 The space needed by the program is the sum of the following components.
 Fixed Space Requirement: This includes the instruction space, for simple variables, fixed size structured
variables, and constants.
 Variable Space Requirement: This consists of space needed by structured variables whose size depends
on particular instance of variables. It also includes the additional space required when the function uses
recursion.

Data Structures Using C | Sudheer Kumar Kasulanati


10

06. Explain Big ‘O’ notation. (or) Asymptotic notation.

Big ‘O’ notation:


 Big O notation helps to determine the time as well as space complexity of algorithms.
 This information is useful to set the prerequisites of algorithms and to develop and design efficient
algorithms in terms of time and space complexity.
 Developers use this notation to reach to the best solution for the given problem.
 Example: For Quick sort algorithm, the worst case complexity is O(n2), For Bubble sort algorithm, the
average case complexity is O(n2). So Quick sort is the better algorithm for sorting.

Most common computing times of Algorithm:

 If the complexity of any algorithm is O(1), it means that the computing time of the algorithm is
constant.
 If the complexity of any algorithm is O(n), it is called linear time which implies that it is directly
proportional to n.
 If the complexity of any algorithm is O(n2), it is called quadratic time.
 If the complexity of any algorithm is O(n3), it is called cubic time.
 If the complexity of any algorithm is O(2 n), it is called exponential time.
 If the complexity of any algorithm is O(log n) or O(n log n), these are called logarithmic times.
 The common computing times of algorithms in the order of performance are as follows:

 O(1)
 O(log n)
 O(n)
 O(n log n)
 O(n2)
 O(n3)
 O(2n)

Data Structures Using C | Sudheer Kumar Kasulanati


11

07. Arrays ADT – Operations, Types.

Arrays:

 Array is a container which can hold a fixed number of items and these items should be of the same
type. Most of the data structures make use of arrays to implement their algorithms. Following are
the important terms to understand the concept of Array.
Element : Each item stored in an array is called an element.
Index : Each location of an element in the array has a numerical index, which is
used to identify the element.

Array Representation:

 Arrays can be declared in different languages in different ways.


 For example, arrays can be declared in C as shown below:
int A[10];
 The above statement creates an array with 10 elements, starting from index 0 to index 9.

Basic Operations

Following are the basic operations supported by an array.


 Traverse : print all the array elements one by one.
 Insertion : Adds an element at the given index.
 Deletion : Deletes an element at the given index.
 Search : Searches an element using the given index or by the value.
 Update : Updates an element at the given index.

Traverse operation:

 Traverse operation is used to display all the elements in the array.

Algorithm:

Let LA be a Linear Array (unordered) with N elements & I is a positive integer with initial value 0.
Following is the algorithm to display all the elements in the list:

1. Start
2. Repeat step 3 & step 4 until I<N.
3. display LA[I].
4. SET I = I+1.
5 Stop

Data Structures Using C | Sudheer Kumar Kasulanati


12

Insertion operation:

 Insert operation is used to insert one or more data elements into an array.
 Based on the requirement, a new element can be added at the beginning, end, or at any given
index of array.

Algorithm:

Let LA be a Linear Array (unordered) with N elements and K is a positive integer such that K<N.
Following is the algorithm where ITEM is inserted at index K of LA:
1. Start
2. Set J = N-1
3. Set N = N+1
4. Repeat steps 5 and 6 while J >= K
5. Set LA[J+1] = LA[J]
6. Set J = J-1
7. Set LA[K] = ITEM
8. Stop

Deletion Operation

Deletion refers to removing an existing element from the array and re-organizing all elements of
an array.
Algorithm:

Consider LA is a linear array with N elements and K is a positive integer such that K<N. Following
is the algorithm to delete an element available at index K of LA.
1. Start
2. Set J = K
3. Repeat steps 4 and 5 while J < N-1
4. Set LA[J] = LA[J + 1]
5. Set J = J+1
6. Set N = N-1
7. Stop

Search Operation

You can perform a search for an array element based on its value or its index.

Algorithm

Consider LA is a linear array with N elements. Following is the algorithm to find an element with a
value of ITEM using sequential search.
1. Start
2. Set J = 0
3. Repeat steps 4 and 5 while J < N
4. IF LA[J] is equal ITEM THEN GOTO STEP 6
5. Set J = J +1
6. PRINT J, ITEM
7. Stop

Data Structures Using C | Sudheer Kumar Kasulanati


13

Update Operation

Update operation refers to updating an existing element from the array at a given index.

Algorithm

Consider LA is a linear array with N elements and K is a positive integer such that K<N. Following
is the algorithm to update an element available at the K th position of LA.

1. Start
2. Set LA[K-1] = ITEM
3. Stop

Types of Arrays:

 Based on the number of indexes to retrieve an element from an array, we can classify Arrays into
two types:
 One dimensional Array (1D Array)
 Multi dimensional Array.

One dimensional Array:

If only one subscript (or) index is needed to reference all the elements in the array, then the array
is called ‘1D Array’.

Memory allocation for 1D Array:

Memory allocation of 1D array is very simple. Suppose, an array A[50] is stored in the memory as
shown below.

Let the memory location where the first element stored is M.

If each element requires one word in the memory, then the location for any element A[i] in the
array can be obtained at address M+(i-1).

In general, an array can be written as A[L……U]. Here L is the lower index & U is the upper index.

Data Structures Using C | Sudheer Kumar Kasulanati


14

If the array is stored starting from the memory location M and for each element it requires W
number of words, then the address for the element A[i] will be M+(i-L)*W

The above formula is know as indexing formula, which is used to map the logical representation of
an array to physical representation.

This is shown in below figure.

Multi dimensional Array:

2D Array (Two-dimensional Array):

Two-dimensional arrays are the collection of homogeneous elements, where the elements are
ordered in number of rows & columns.

Example: m x n matrix, where m denotes the number of rows & n denotes the number of columns.

a11 a12 a13 ………………. a1n

a21 a22 a23 ………………. a2n

a31 a32 a33 ………………. a3n

. . . ……………….. .
. . . ……………….. .
. . . ……………….. .

am1 am2 am3 ………………. amn

The subscript of an array element aij represents the ith row & jth column.

Memory representation of a matrix:

Like 1D arrays, matrices are also stored in contiguous memory locations. The elements of a matrix are stored on a
row by row.

Data Structures Using C | Sudheer Kumar Kasulanati


15

Example: Consider a matrix of order 3x3.

a11 a12 a13

a21 a22 a23

a31 a32 a33

This matrix can be represented in memory as shown below.

a11 1
a12 2
a13 3
a21 4
a22 5
a23 6
a31 7
a32 8
a33 9

08. Write about applications of two-dimensional arrays (Sparse Matrix).

Applications of two-dimensional arrays: Sparse Matrix

 Sparse matrix is a matrix with the majority of its elements equal to zero.
 If the majority elements are non-zero elements, then it is called dense matrix.
 The below program checks whether given matrix is sparse matrix or not & prints number of zeroes in it.

#include<stdio.h>
void main(){
int a[10][10], i, j, m, n, count=0;
printf("Enter size of matrix...");
scanf("%d %d",&m,&n);
printf("Enter elements of the matrix...");
for(i=0;i<m;i++)
for(j=0;j<n;j++){
scanf("%d",&a[i][j]);
if(a[i][j]==0) count++;
}
if (count>(m*n)/2) printf(" Given matrix is Sparse Matrix...");
else printf("Given matrix is not Sparse Matrix...");
printf(“There are %d number of zeroes”,count);
}

Output:
Enter size of matrix...
2 3
Enter elements of the matrix...
12 0 0
0 0 23
Given matrix is Sparse Matrix...
There are 6 number of zeroes

Data Structures Using C | Sudheer Kumar Kasulanati


16

09. Write about Dynamic Memory Allocation in C.

Dynamic memory allocation in C

 The concept of dynamic memory allocation in c language enables the C programmer to allocate memory at
runtime.
 Dynamic memory allocation in c language is possible by 4 functions of stdlib.h header file.
 malloc() - allocates single block of requested memory.
 calloc() - allocates multiple block of requested memory.
 realloc() - reallocates the memory occupied by malloc() or calloc() functions.
 free() - frees the dynamically allocated memory.

 Before learning above functions, let's understand the difference between static memory allocation and
dynamic memory allocation.

STATIC MEMORY ALLOCATION DYNAMIC MEMORY ALLOCATION


memory allocated at compile time memory allocated at run time
memory can’t be increased memory can be increased
used in Arrays used in linked lists

malloc() function in C

 The malloc() function allocates single block of requested memory.


 It doesn't initialize memory at execution time, so it has garbage value initially.
 It returns NULL if memory is not sufficient.
 The syntax of malloc() function is given below:
ptr=(cast-type*)malloc(byte-size)
 Let's see the example of malloc() function.

#include<stdio.h>
#include<stdlib.h>
void main(){
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL){
printf("Sorry! unable to allocate memory");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i){
scanf("%d",ptr+i);
sum+=*(ptr+i);
}
printf("Sum=%d",sum);
free(ptr);
}

Output:

Enter elements of array: 3


Enter elements of array: 10
10
10
Sum=30
Data Structures Using C | Sudheer Kumar Kasulanati
17

calloc() function in C

 The calloc() function allocates multiple blocks of requested memory.


 It initially initialize all bytes to zero. It returns NULL if memory is not sufficient.
 The syntax of calloc() function is given below:
ptr=(cast-type*)calloc(number, byte-size)
 Let's see the example of calloc() function.

#include<stdio.h>
#include<stdlib.h>
void main(){
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)calloc(n,sizeof(int)); //memory allocated using calloc
if(ptr==NULL)
{
printf("Sorry! unable to allocate memory");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i)
{
scanf("%d",ptr+i);
sum+=*(ptr+i);
}
printf("Sum=%d",sum);
free(ptr);
}

Output:
Enter elements of array: 3
Enter elements of array: 10
10
10
Sum=30

realloc() function in C

 If memory is not sufficient for malloc() or calloc(), you can reallocate the memory by realloc()
function. In short, it changes the memory size.
 Syntax of realloc() function.
ptr=realloc(ptr, new-size)

free() function in C

 The memory occupied by malloc() or calloc() functions must be released by calling free() function.
Otherwise, it will consume memory until program exit.
 Syntax of free() function.
free(ptr)

Data Structures Using C | Sudheer Kumar Kasulanati


18

Data Structures Using C | Sudheer Kumar Kasulanati


19

UNIT 2
Linked Lists

01. Write about single linked list & it’s operations.

Linked Lists:

 Linked list is a linear data structure which consists of group of nodes in a sequence.
 Each node has data & address of next node.
 A node may have any number of data elements.

Advantages of linked lists:

 Linked lists are dynamic in nature which allocates the memory when required.
 Insertion & deletion can be implemented easily using linked lists.
 We don’t need to know the size of the list in advance.
 Linked lists allow us to insert elements at the beginning (or) at the end of the list.
 Linked lists are used to implement stacks, queues, trees, graphs etc.

Disadvantages of linked lists:

 The memory is wasted as pointers require extra memory for storage.


 The elements can’t be accessed randomly, each element has to be accessed sequentially.
 Reverse traversing is difficult in linked lists.

Representation of linked lists:

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

 Each node in a list consists of at least two parts:


 1) data
 2) Pointer (Or Reference) to the next node
 In C, each node can be represented as a structure. The node structure contains a reference of
next node in the list.
 In C, we can create a node as shown below:

struct node{
int data;
struct node *next;
};
struct node *head=NULL;
struct node *nn=NULL;

 Here nn is new node. This will be created using malloc function as shown below.
nn = (struct node *)malloc(sizeof(struct node));

Data Structures Using C | Sudheer Kumar Kasulanati


20

Types of Linked Lists:

 There are mainly 3 types of linked lists:


Single linked list
Doubly linked list
Circular linked list

Single linked list:

 In a single linked list, each node contains only one link which points to the next node in the
list.
 The below figure shows a single linked list with 5 nodes.

 As shown above, HEAD points to the address of Node 1.


 Every node stores data along with the address of next node.
 Last node does not points to any node, so it contains data & NULL.
 If we know the address of the HEAD node, we can trace all the elements in the list.
 In a single linked list, we can move for elements from left to right only. So it is called one
way list.

Representation of Linked list in Memory:

 There are two ways to represent linked lists in the memory.


 static representation using arrays.
 dynamic representation using free pool of storage.

1. Static representation:

 In static representation of single linked list, two arrays are used.


 One array is used to store the data & one array to store links.
 The static representation will be as shown below:

Data Structures Using C | Sudheer Kumar Kasulanati


21

2. Dynamic representation:

 This is the efficient way to represent a linked list.


 This representation use free pool of storage.
 In this method, there is a memory bank, which is a collection of free memory spaces &
memory manager.
 While creating a node, memory manager will search the memory bank & allocates memory to
the node.
 If there are nodes in the memory, which are not in use any more, the occupied memory space
by these nodes will also be released to memory bank. This is known as Garbage Collector.
 This type of memory management is called “Dynamic Memory Management”.

Operations on a single linked list:

 Following are the different operations we can perform on a single linked list:
 Traversing the list.
 Inserting element into the list.
 Delete a node from the list.
 Searching for an element in the list.
 Merging two linked lists.

Traversing the list:

 While traversing a single linked list, we have to visit every node in the list, starting from the first
node to the last node.
 Following is the Algorithm to visit all the nodes in the list:

STEP 1: SET PTR = HEAD


STEP 2: IF PTR = NULL
DISPLAY "LIST IS EMPTY"
GOTO STEP 6
STEP 3: REPEAT STEP 4 AND 5 UNTIL (PTR != NULL)
STEP 4: DISPLAY PTR → DATA
STEP 5: PTR = PTR → NEXT
STEP 6: EXIT

Data Structures Using C | Sudheer Kumar Kasulanati


22

Inserting element into the list:

 In a single linked list, there are various combinations to insert an element.


 Insert at the front.
 Insert at the end.
 Insert at any other position.

Insert at the front:

 The new node is always added before the head of the given Linked List.
 Newly added node becomes the new head of the Linked List.
 For example, if the given Linked List is 10 15 20 25 and we add an item 5 at the front, then
the Linked List becomes 5 10 15 20 25. Let us call the function that adds at the front of the
list is insert(). The insert() must receive a pointer to the head pointer, because push must change
the head pointer to point to the new node.

 Following is the code to insert an element at front:

public void push(int new_data){


new_node = (struct node *)malloc(sizeof(struct node));
new_node.data = new_data;
new_node.next = head;
head = new_node;
}

Insert at the end:

 The new node is always added after the last node of the given Linked List.
 For example if the given Linked List is 5  10 15  20  25 and we add an item 30 at the end,
then the Linked List becomes 5 10 15 20 25 30.
 Since a Linked List is typically represented by the head of it, we have to traverse the list till end
and then change the next of last node to new node.
 The next of new node will be NULL & next of last node will be new node.

Data Structures Using C | Sudheer Kumar Kasulanati


23

 Following is the code to insert element at end of the list:

public void append(int new_data){


new_node = (struct node *)malloc(sizeof(struct node));
new_node.data = new_data;
if (head == null){
head = new_node;
return;
}
new_node.next = null;
Node last = head;
while (last.next != null)
last = last.next;
last.next = new_node;
return;
}

Insert at the any position:

 We are given, after which element we have to insert new node.


 For example if the given Linked List is 5  10 15  20  25 and we add an item 40 after the
element 10, then the Linked List becomes 5 10  40 15 20 25.

 Following is the code to insert element after the given element:

public void insertAfter(Node prev_node, int new_data){


new_node = (struct node *)malloc(sizeof(struct node));
new_node.data = new_data;
new_node.next = prev_node.next;
prev_node.next = new_node;
}

Deleting an element from the single linked list:

 To delete a node from linked list, we need to do following steps.


 Find previous node of the node to be deleted.
 Change the next of previous node.
 Free memory for the node to be deleted.
Data Structures Using C | Sudheer Kumar Kasulanati
24

 Following is the code to delete element in the single linked list:

void deleteNode(int key){


Node temp = head, prev = null;
if (temp != null && temp.data == key){
head = temp.next;
return;
}
while (temp != null && temp.data != key){
prev = temp;
temp = temp.next;
}
if (temp == null) return;
prev.next = temp.next;
}

Searching for an element in the single linked list:

 To search for an element in the list, we have to traverse through the list starting from first node till
we found the searching element (or) till we reach the end of the list.
 For example, if the key to be searched is 11 and linked list is 1421113010,
then the function should return true. If the key to be searched is 25, then the function should
return false.
 Following is the code to search an element in the list:

public boolean search(Node head, int x){


Node current = head;
while (current != null){
if (current.data == x)
return true; //data found
current = current.next;
}
return false; //data not found
}

Merging two linked lists:

 Merging two linked lists is the process of creating link between the last node of first list & first node
of second list.
 To do this, we need to traverse through all the nodes in the first list till we find last node.
 Replace the NULL (which is at link part of last node) with HEAD of second list.
 Following is the code to merge two linked lists:

Node merge(LinkedList First, LinkedList Second) {


Node original = First.first;
Node previous = null;
Node current = First.first;
Data Structures Using C | Sudheer Kumar Kasulanati
25

while (current != null) {


previous = current;
current = current.next;
}
previous.next = Second.first;
return original;
}

Data Structures Using C | Sudheer Kumar Kasulanati


26

02. Write about doubly linked list & it’s operations.

Doubly Linked Lists:

 In a single linked list, we can traverse from starting node to any other node in one direction only.
That’s why it is called one way list.
 But, in Doubly Linked Lists, we can traverse through nodes in both directions, either from left to
right (or) right to left.
 This can be done by maintain two links instead of one as in single linked list.
 The structure of a node in doubly linked list is represented as shown below:

 In a doubly linked list, The HEAD node contains NULL in it’s left pointer. The last node contains
NULL in it’s right pointer.
 All the remaining nodes contain address of immediate predecessor in Left pointer & address of
immediate successor in Right pointer.

Doubly Linked Lists - Operations:

 We can perform various operations on doubly linked list.


 Insert an element in the list.
 Delete an element in the list.
 Searching an element in the list
 Traversing through the list.

Insert an element in DLL:

 Like in Single Linked List, we can perform insertion in DLL in various cases.

Insert an element at front:

 The new node is always added before the HEAD of the given Linked List.
 Newly added node becomes the new HEAD of DLL.
 For example if the given Linked List is 10152025 and we add an item 5 at the front, then the
Linked List becomes 510152025.
 Let us call the function that adds at the front of the list is insert().
 The insert() must receive a pointer to the HEAD pointer.

Data Structures Using C | Sudheer Kumar Kasulanati


27

 Following is the code to insert element at front in DLL:

public void push(int new_data){


new_Node = (struct node *)malloc(sizeof(struct node));
new_Node.data = new_data;
new_Node.next = head;
new_Node.prev = null;
if (head != null)
head.prev = new_Node;
head = new_Node;
}

Insert an element at end:

 The new node is always added after the last node of the given Linked List.
 For example if the given Linked List is 10152025 and we add an item 5 at the end, then the
Linked List becomes 101520255.
 To insert element after last node, we need to traverse the list till we find last node.

 Following is the code to insert element at end in DLL:

void append(int new_data){


new_node = (struct node *)malloc(sizeof(struct node));
new_node.data = new_data;
Node last = head;
new_node.next = null;
if (head == null) {
new_node.prev = null;
head = new_node;
return;
}
while (last.next != null)
last = last.next;
last.next = new_node;
new_node.prev = last;
}

Data Structures Using C | Sudheer Kumar Kasulanati


28

Insert an element after a given node:

 Traverse through the list until we find given node (Lets call it prev_node).
 Put prev_nodenext in New_Nodenext.
 Put prev_node in New_Nodeprev.
 Put New_Node in prev_nodenext.
 Put New_Node in prev_nodenextprev.

 Following is the code to insert element after given node.

public void InsertAfter(Node prev_Node, int new_data){


if (prev_Node == null) {
System.out.println("The given previous node cannot be NULL ");
return;
}
new_node = (struct node *)malloc(sizeof(struct node));
new_node.data = new_data;
new_node.next = prev_Node.next;
prev_Node.next = new_node;
new_node.prev = prev_Node;
if (new_node.next != null)
new_node.next.prev = new_node;
}

Delete an element in DLL:

 When we are deleting a node (let’s call it as del_node), we have to do some adjustments.
 We need to change the immediate predecessornext to del_nodenext.
 We need to change immediate successorprev to del_nodeprev.

Algorithm:

Step 1 : If you want to delete a head node.


a) Change the head pointer to next of current node (head here).
b) Change the previous pointer of next node to current node previous.
Step 2 : If you want to delete middle node.
a) Change the previous pointer of next node to current node previous.
b) Change the previous node next pointer to next of current node.
c) Delete the node. (current node)
d) If previous or next is NULL you need not delete them. (for deleting last node)

Data Structures Using C | Sudheer Kumar Kasulanati


29

Example:

Data Structures Using C | Sudheer Kumar Kasulanati


30

03. Write about circular linked list.

Circular Linked lists:

Circular Linked List is a variation of Linked list in which the first element points to the last element
and the last element points to the first element. Both Singly Linked List and Doubly Linked List can be
made into a circular linked list.

Singly Linked List as Circular:

In singly linked list, the next pointer of the last node points to the first node.

Doubly Linked List as Circular:

In doubly linked list, the next pointer of the last node points to the first node and the previous pointer
of the first node points to the last node making the circular in both directions.

As per the above illustration, following are the important points to be considered.
- The last link's next points to the first link of the list in both single as well as doubly linked list.
- The first link's previous points to the last of the list in case of doubly linked list.
- Following are the important operations supported by a circular list.
insert − Inserts an element at the start of the list.
delete − Deletes an element from the start of the list.
display − Displays the list.

Advantages of circular linked lists:

 Accessibility of an element in the list:


In ordinary list, a node is accessible from a particular node from a HEADER node only, But in circular linked lists,
every node is accessible from any other node.
 NULL link problem:
The NULL value in the link field may cause some problem if proper care is not taken.
 Easy to implement operations:
Some operations are very easy to implement with circular linked list than with ordinary linked list.
Ex: operations like merging, deleting entire list.

Disadvantages of circular linked lists:

 If proper care is not taken, it is possible to get trapped into an infinite loop.
 This problem occurs, when we are unable to detect the end of the list while moving from one node to another
node.

Data Structures Using C | Sudheer Kumar Kasulanati


31

04. Write differences between Array & Linked list.

Differences between Array and Linked List:

S.No Array Linked List

Array is a collection of elements Linked list is an ordered collection of


01 having same data type with common elements which are connected by links.
name.

Elements can be accessed randomly. Elements cannot be accessed randomly.


02
It can be accessed only sequentially.

Array elements can be stored in Linked list elements can be stored at any
03 consecutive memory locations. available place as address of node is
stored in previous node.

Insert and delete operation takes Insert and delete operation cannot take
04 more time in array. more time. It performs operation in fast
and in easy way.

05 Memory is allocated at compile time. Memory is allocated at run time.

It can be single dimensional, two It can be single, doubly or circular linked


06
dimensional or multidimensional. list.

Each array element is independent Location or address of element is stored


07 and does not have a connection with in the link part of previous element or
previous element. node.

Array elements cannot be added, The nodes in the linked list can be added
08
deleted once it is declared. and deleted from the list.

In array, elements can be modified In linked list, modifying the node is a


09
easily by identifying the index value. complex process.

Data Structures Using C | Sudheer Kumar Kasulanati


32

05. Write applications of linked lists.

Applications of linked list data structure:


A linked list is a linear data structure, in which the elements are not stored at contiguous memory locations. The
elements in a linked list are linked using pointers as shown in the below image:

Applications of linked list in computer science:

 Implementation of stacks and queues.


 Implementation of graphs: Adjacency list representation of graphs is the most popular which uses a linked list to
store adjacent vertices.
 Dynamic memory allocation: We use a linked list of free blocks.
 Maintaining a directory of names.
 Performing arithmetic operations on long integers.
 Manipulation of polynomials by storing constants in the node of the linked list.
 Representing sparse matrices.

Applications of linked list in the real world:


1. Image viewer – Previous and next images are linked and can be accessed by the next and previous buttons.
2. Previous and next page in a web browser – We can access the previous and next URL searched in a web
browser by pressing the back and next buttons since they are linked as a linked list.
3. Music Player – Songs in the music player are linked to the previous and next songs. So you can play songs
either from starting or ending of the list.
4. GPS navigation systems- Linked lists can be used to store and manage a list of locations and routes, allowing
users to easily navigate to their desired destination.
5. Robotics- Linked lists can be used to implement control systems for robots, allowing them to navigate and
interact with their environment.
6. Task Scheduling- Operating systems use linked lists to manage task scheduling, where each process waiting to
be executed is represented as a node in the list.
7. Image Processing- Linked lists can be used to represent images, where each pixel is represented as a node in
the list.
8. File Systems- File systems use linked lists to represent the hierarchical structure of directories, where each
directory or file is represented as a node in the list.
9. Symbol Table- Compilers use linked lists to build a symbol table, which is a data structure that stores
information about identifiers used in a program.
10. Undo/Redo Functionality- Many software applications implement undo/redo functionality using linked lists,
where each action that can be undone is represented as a node in a doubly linked list.
11. Speech Recognition- Speech recognition software uses linked lists to represent the possible phonetic
pronunciations of a word, where each possible pronunciation is represented as a node in the list.
12. Polynomial Representation- Polynomials can be represented using linked lists, where each term in the
polynomial is represented as a node in the list.
13. Simulation of Physical Systems- Linked lists can be used to simulate physical systems, where each element in
the list represents a discrete point in time and the state of the system at that time.

Data Structures Using C | Sudheer Kumar Kasulanati


33

UNIT 3
Stacks & Queues

01. Stacks – ADT, Operations.

STACKS:

 Stack is a data structure that allows adding and removing elements in a particular order.
 Every time an element is added it goes on top of the stack.
 The only element can be removed is the element at top of the stack.
 Stacks are sometimes called as Last-In-First-Out (LIFO) lists i.e. the element which is inserted first
in the stack, will be deleted last from the stack.
 When we want to push an element into the stack, check whether the stack is full (or) not. If not,
‘top’ value is incremented & the element is stored in that position.
 When we want to pop an element from the stack, check whether the stack is empty (or) not. If not,
‘top’ value is decremented.

Features of stack:

 Stack is a list of elements of similar datatype.


 Stack is a LIFO (Last In First Out) structure.
 push() function is used to insert new element into the stack.
 pop() function is used to delete an element from the stack.
 Stack is said to be in overflow state when it is full, underflow state when it is empty.

Applications of Stack

 Stacks can be used for expression evaluation.


 Stacks can be used to check parenthesis matching in an expression.
 Stacks can be used for Conversion from one form of expression to another.
 Stacks can be used for Memory Management.
 Stack data structures are used in backtracking problems.

Operations on Stack

There are various operations which can be performed on stack.

Data Structures Using C | Sudheer Kumar Kasulanati


34

1. Push : Adding an element onto the stack.

Algorithm to push element into the stack:

Step 1: START
Step 2: if (top=n-1) then display “stack is full”
goto Step 4.
Step 3: top = top+1
stack(top)  item
Step 4: STOP

2. Pop : Removing an element from the stack

Algorithm to remove element from the stack:

Step 1: START
Step 2: if (top=-1) then display “stack is empty”
goto Step 4.
Step 3: display the removed item at stack(top).
top  top-1
Step 4: STOP

Data Structures Using C | Sudheer Kumar Kasulanati


35

3. Peek : Look all the elements of stack without removing them.

Different scenarios of stacks:

Scenario 1 : Stack is empty

The stack is called empty if it doesn't contain any element inside it. At this stage, the value of variable
top is -1.

Scenario 2 : Stack is not empty

Value of top will get increased by 1 every time when we add any element to the stack. In the following
stack, After adding three elements, top = 2.

Scenario 3 : Deletion of an element


Value of top will get decreased by 1 whenever an element is deleted from the stack.
In the following stack, after deleting 10 from the stack, top = 1.

Data Structures Using C | Sudheer Kumar Kasulanati


36

Status of stack depends on Top position:

Top position Status of stack

-1 Empty

0 One element in stack

N-1 stack is full with N elements

N stack overflow

02. Stacks – Arrays & Linked list representation.

Array implementation of Stack:

 In array implementation, the stack is formed by using the array.


 All the operations regarding the stack are performed using arrays.
 Lets see how each operation can be implemented on the stack using array data structure.

Adding an element into the stack (push operation):

 Adding an element into the top of the stack is referred to as push operation. Push operation
involves following two steps.
 Increment the variable Top so that it can now refer to the next memory location.
 Add element at the position of incremented top. This is referred to as adding new element at
the top of the stack.
 Stack is overflown when we try to insert an element into a completely filled stack, so our main
function must always avoid stack overflow condition.

push() operation code in C:


boolean push (int x){
if(top == maxsize-1){
printf("Stack is Overflow !!");
return false;
}
else{
top++;
A[top]=x;
printf("Item pushed");
return true;
}
}

Deleting an element from a stack (Pop operation):

 Deletion of an element from the top of the stack is called pop operation.
 The top most element of the stack is stored in an another variable and then the top is
decremented by 1.
 The operation returns the deleted value that was stored in another variable.
 The underflow condition occurs when we try to delete an element from an already empty stack.
Data Structures Using C | Sudheer Kumar Kasulanati
37

pop() operation code in C:


boolean pop (){
if (top == -1) {
printf("Underflow !!");
return false;
}
else{
top --;
printf("Item popped");
return true;
}
}

Linked list implementation of stack:

 Instead of using array, we can also use linked list to implement stack.
 Linked list allocates the memory dynamically.
 However, time complexity in both the scenarios is same for all the operations i.e. push, pop
and peek.
 In linked list implementation of stack, the nodes are maintained non-contiguously in the
memory.
 Each node contains a pointer to its immediate successor node in the stack. Stack is said to be
overflown if the space left in the memory heap is not enough to create a node.

 The last node in the stack always contains null in its address field.
 Following are the operations performed on stack using linked list implementation.

Adding a node to the stack (Push operation)

 Adding a node to the stack is referred to as push operation.


 Pushing an element to a stack in linked list implementation is different from that of an array
implementation.
 In order to push an element onto the stack, the following steps are involved.
1. Create a node first and allocate memory to it.
2. If the list is empty then the item is to be pushed as the start node of the list. This includes
assigning value to the data part of the node and assign null to the address part of the node.
3. If there are some nodes in the list already, then we have to add the new element in the
beginning of the list (to not violate the property of the stack).
4. For this purpose, assign the address of the starting element to the address field of the new
node and make the new node, the starting node of the list.
Data Structures Using C | Sudheer Kumar Kasulanati
38

Deleting a node from the stack (POP operation)

 Deleting a node from the top of stack is referred to as pop operation.


 Deleting a node from the linked list implementation of stack is different from that in the array
implementation.
 In order to pop an element from the stack, we need to follow the following steps :
 Check for the underflow condition: The underflow condition occurs when we try to pop from
an already empty stack. The stack will be empty if the head pointer of the list points to null.
 Adjust the head pointer accordingly: In stack, the elements are popped only from one end,
therefore, the value stored in the head pointer must be deleted and the node must be freed.
The next node of the head node now becomes the head node.

Data Structures Using C | Sudheer Kumar Kasulanati


39

Applications of Stack

Expression Evaluation:
Stack is used to evaluate prefix, postfix and infix expressions.
Expression Conversion:
An expression can be represented in prefix, postfix or infix notation. Stack can be used to convert
one form of expression to another.
Syntax Parsing:
Many compilers use a stack for parsing the syntax of expressions, program blocks etc. before
translating into low level code.
Backtracking:
Suppose we are finding a path for solving maze problem. We choose a path and after following it
we realize that it is wrong. Now we need to go back to the beginning of the path to start with new
path. This can be done with the help of stack.
Parenthesis Checking:
Stack is used to check the proper opening and closing of parenthesis.
String Reversal:
Stack is used to reverse a string. We push the characters of string one by one into stack and then
pop character from stack.
Function Call:
Stack is used to keep information about the active functions or sub routines.

Data Structures Using C | Sudheer Kumar Kasulanati


40

03. Write about Applications of stacks. (Infix to Postfix expression)

Infix to Postfix conversion:

 The algorithm for the conversion is as follows:


Step 1: Repeat following steps until stack is empty
Step 2: Scan the infix string from left to right.
Step 3: If the scanned character is Left parenthesis ‘(‘, push it into the stack.
Step 4: If the scanned character is Right parenthesis ‘)’, pop the elements from the stack
until we get ‘(‘.
Step 5: If the scanned character is operand, add it to postfix string.
Step 6: If the scanned character is an operator & if the stack is empty (or) top of the stack
is ‘(‘, push the character to the stack.
Step 7: If the scanned character is an operator & if the stack is not empty, compare the
precedence of the character with the element on top of the stack.
Step 8: If the top of the stack element has higher precedence, pop the stack & add the popped
element to the postfix string. Push the scanned character onto the stack.
Step 9: If the top of the stack element has lower precedence, push the character onto the
stack.
Step 10: Stop

Example: Convert infix expression A + B * C.

Data Structures Using C | Sudheer Kumar Kasulanati


41

04. Write about recursion. Write differences between Recursion & Iteration.

RECURSION:
 Some computer programming languages allow a module or function to call itself. This technique is known
as recursion.
 In recursion, a function α either calls itself directly or calls a function β that in turn calls the original
function α.
 The function α is called recursive function.

 Example 1 − a function calling itself.

int factorial(int n) {
if(n < = 1)
return 1;
else
return n*factorial(n-1);
}

 Example 2 − a function calls another function, which in turn calls it again.

void function1(){
// some code
function2();
// some code
}
void function2(){
// some code
function1();
// some code
}

Principles of Recursion:

Some basic principles which are used while designing algorithms with recursion are:

 Find the key step: When beginning with the design of algorithms through recursion, one should try to
find out the ‘key step’ for the solution. Once you have executed the key step, find out whether the
remainder of the problem can be solved in the same way, and modify the step if necessary.

 Find a stopping rule: The stopping rule indicates that the problem is done & execution of the algorithm
can be stopped.

 Outline your algorithm: After determining the key step for the problem and finding the cases which are
to be handled, the next step is to combine these to using an ‘if’ statement to select between them. The
main program and the procedure for recursion are now to be written to carry the key step through until
the stopping rule applies.

 Check termination: Care should be taken to ensure that recursion will always terminate after the finite
number of steps and the stopping rule should also be satisfied.

Data Structures Using C | Sudheer Kumar Kasulanati


42

Differences between Recursion & Iteration:

Recursion Iteration

A technique in which the function calls


Iteration is a technique that
itself in its body to solve the problem,
Definition repetitively executes a code block
typically breaking into smaller and more
until the condition is not satisfied.
manageable sub-problems.

The iteration format includes


Syntax There is a termination condition specified. initialization, condition, and
increment/decrement of a variable.

Control
Function call stack. Looping Constructs (for, while etc.)
Structure

Problem-
Solving Divide and Conquer. Sequential Execution.
Approach

Lower than recursion due to the


Time Higher due to the overhead of maintaining
absence of the overhead of
Complexity the function call stack.
function calls.

Generally lower than recursion due


Space
Higher than iteration. to the absence of the overhead
Complexity
function calls.

Memory Uses more memory. Uses less memory.

Faster than Recursion as it uses


Speed Slower than Iteration.
less memory.

Application For Functions. For Loops.

Tree/Graph Traversal or the problem that


Preferred when tasks require
Usage can be broken down into similar sub-
repetition of similar tasks.
problems.

Data Structures Using C | Sudheer Kumar Kasulanati


43

05. Queues – ADT, Operations.

QUEUES:
 Queue is a data structure that allows inserting elements from one end (REAR or tail) & deleting
elements from other end (FRONT or head).
 Queue is a FIFO data structure, which means that the element inserted first will be removed first.
 The process to add an element into queue is called ‘Enqueue’ and the process of removing the
element is called ‘Dequeue’.

 When we want to add an element into the queue, we need to check whether the queue is full (or)
not. If the queue is not full, then ‘rear’ is incremented & element is stored in that position.
 When we want to remove an element from the queue, we have to check whether the queue is
empty (or) not. If the queue is not empty, ‘front’ is incremented.

Operations on Queue:

Following are the basic operations performed on a Queue.


Operations Description
enqueue() Used to add an element into the queue
dequeue() Used to remove an element from the queue
init() Used to initialize the queue
front() Used to get the front item from the queue
rear() Used to get the last item from a queue
isFull() checks whether the queue is full or not

Enqueue Operation:

 Queues maintain two data pointers, front and rear. Therefore, its operations are
comparatively difficult to implement than that of stacks.
 The following steps should be taken to enqueue (insert) data into a queue –

Step 1 − Check if the queue is full.


Step 2 − If the queue is full, produce overflow error and exit.
Step 3 − If the queue is not full, increment rear to point the next empty space.
Step 4 − Add data element to the queue location, where the rear is pointing.
Step 5 − return success.

Data Structures Using C | Sudheer Kumar Kasulanati


44

Algorithm for Enqueue operation:

Step 1: START
Step 2: if queue is full display “overflow” goto step 5
Step 3: rear  rear+1
Step 4: queue[rear]  data
Step 5: STOP

Dequeue operation:
 Accessing data from the queue is a process of two tasks − access the data where front is
pointing and remove the data after access.
 The following steps are taken to perform dequeue operation:
Step 1 − Check if the queue is empty.
Step 2 − If the queue is empty, produce underflow error and exit.
Step 3 − If the queue is not empty, access the data where front is pointing.
Step 4 − Increment front pointer to point to the next available data element.
Step 5 − Return success.

Algorithm for dequeue operation

Step 1: START
Step 2: if queue is empty display “underflow”
goto step 5
Step 3: return queue[front]
Step 4: front  front+1
Step 5: STOP
Data Structures Using C | Sudheer Kumar Kasulanati
45

06. Queues – Arrays & Linked list representation.

Array implementation of queue:


 In queue, insertion and deletion happen at the opposite ends, so implementation is not as
simple as stack.
 To implement a queue using array, create an array A of size n and take two
variables front and rear both of which will be initialized to 0 which means the queue is
currently empty.
 Element rear is the index upto which the elements are stored in the array and front is the
index of the first element of the array.
 Now, some of the implementation of queue operations are as follows:

Enqueue: Addition of an element to the queue. Adding an element will be performed after
checking whether the queue is full or not.
If rear < n which indicates that the array is not full then store the element at A[rear] and
increment rear by 1 but if rear = n then it is said to be an Overflow condition as the array is
full.

Dequeue: Removal of an element from the queue. An element can only be deleted when there
is at least one element to delete i.e. rear > 0.
Now, element at A[front] will be deleted & front is incremented.

Display: Print all elements of the queue. If the queue is non-empty, traverse and print all the
elements from index front to rear-1.

Example:
Consider a queue, containing 6 elements as shown below.

 Add 66 into the queue using Enqueue() operation.

Data Structures Using C | Sudheer Kumar Kasulanati


46

 Delete 10 from the queue using Dequeue() operation.

Below is the C program to implement of a queue using an array:


#include<stdio.h>
int A[5], front=0, rear=0;
void Enqueue(int);
void Dequeue();
void display();
void main(){
clrscr();
Enqueue(98);
Enqueue(85);
Enqueue(18);
Enqueue(33);
Enqueue(90);
display();
Dequeue();
display();
getch();
}
void Enqueue(int data){
if (rear == 5) printf("Queue is full...");
else A[rear++] = data;
}
void Dequeue(){
if (rear==front) printf("Queue is Empty...");
else front++;
}
void display(){
int i;
if (rear==front) printf("Queue is empty...");
else for(i=rear-1; i>=front; i--)
printf("%d ",A[i]);
printf("\n");
}

Output:

90 33 18 85 98
90 33 18 85

Data Structures Using C | Sudheer Kumar Kasulanati


47

Linked list implementation of Queue:

 The major problem with the queue implemented using an array is, It will work for an only fixed
number of data values.
 That means, the amount of data must be specified at the beginning itself.
 Queue using an array is not suitable when we don't know the size of data which we are going to
use.
 A queue data structure can be implemented using a linked list data structure. The queue which is
implemented using a linked list can work for an unlimited number of values.
 That means, queue using linked list can work for the variable size of data (No need to fix the size at
the beginning of the implementation).
 The Queue implemented using linked list can organize as many data values as we want.
 In linked list implementation of a queue, the last inserted node is always pointed by 'rear' and the
first node is always pointed by 'front'.

Example:

 In above example, the last inserted node is 50 and it is pointed by 'rear' and the first inserted node
is 10 and it is pointed by 'front'.
 The order of elements inserted is 10, 15, 22 and 50.

Enqueue(value) - Inserting an element into the Queue


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

 Step 1 - Create a newNode with given value & Check whether queue is Empty or Not.
 Step 2 - If it is Empty then, set newnode → next = null,
front = newNode and rear = newNode.
 Step 3 - If it is Not Empty then, set newnode → next = rear and rear = newNode

For example, if we add element 83 using Enqueue() operation, the above queue will be as shown
below:

Dequeue() - Deleting an Element from Queue


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

 Step 1 - Check whether queue is Empty or Not.


 Step 2 - If it is Empty, then display "Queue is Empty”.
 Step 3 - If it is Not Empty then, set 'temp' to 'rear'.
 Step 4 - Traverse through the queue until we get temp → next = front.
Then set temp → next = null' and front = temp.

Data Structures Using C | Sudheer Kumar Kasulanati


48

For example, remove element 10 using Dequeue() operation, the above queue will be as
shown below:

display() - Displaying the elements of Queue

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

 Step 1 - Check whether queue is Empty.


 Step 2 - If it is Empty then, display 'Queue is Empty'.
 Step 3 - If it is Not Empty, define a Node pointer 'temp' and initialize with rear.
 Step 4 - Display 'temp → data' and move it to the next node. Repeat the same until
'temp' reaches to 'null'.

07. Write about ‘Circular Queues’.

Circular queues:

 Some times, Even if there are empty cells at the beginning of the array, we can’t insert a new item,
because rear reaches end of the array.
 To avoid this problem, we use circular queues. In circular queues, front & rear wrap around to the
beginning of the array.
 Circular Queue is a linear data structure in which the operations are performed based on FIFO
(First In First Out) principle and the last position is connected back to the first position to make a
circle. It is also called ‘Ring Buffer’.

 In the following example, we have a queue with 5 elements.

 If we remove 2 elements, the queue will be as shown below.

 As shown above, Rear reaches to the end of the array & Front reaches to index 2.
 Using circular queue, we can insert element at index 0, even if ‘Rear’ reaches end.

Data Structures Using C | Sudheer Kumar Kasulanati


49

Operations on Circular Queue:


 Enqueue(value): This function is used to insert an element into the circular queue.
In a circular queue, the new element is always inserted at Rear position.
 Steps:
Check whether queue is Full – Check ((rear==SIZE && front == 0) || (rear==front)).
If it is full then display Queue is full.
If queue is not full then, if rear<SIZE, then insert the element at rear position & increment the
rear. If (rear==SIZE && front!=0), then set rear=0 and insert the element at rear position &
increment the rear..

 Dequeue(): This function is used to delete an element from the circular queue. In a circular
queue, the element is always deleted from front position.

 Steps:
Check whether queue is Empty means check (front==0 && rear==0).
If it is empty then display Queue is empty.
If queue is not empty then Check if (front==rear-1) if it is true then set front=rear= 0 else
check if (front==size-1), if it is true then set front=0.

08. Write about ‘DEQUE’ (Double Ended Queues).

Deque (Double Ended Queue):


 A deque is also known as double-ended queue.
 It is an ordered collection of items similar to the queue.
 It has two ends, a front and a rear, and the items remain positioned in the collection.
 In a deque new items can be added at either the front or the rear. Similarly, existing items can
be removed from either end.
 The deque provides all the capabilities of stacks and queues in a single data structure.
 The deque abstract data type is defined by the following operations.
Deque ADT operations:
The deque operations are given below.
 deque() : creates a new deque that is empty.
 addFront(item) : adds a new item to the front of the deque.
 addRear(item) : adds a new item to the rear of the deque.
 removeFront() : removes the front item from the deque. The deque is modified.
 removeRear() : removes the rear item from the deque. The deque is modified.
 isEmpty() : tests to see whether the deque is empty or not.
 size() : returns the number of items in the deque.

Example: Assume that d is a deque, that has been created and is currently empty. Following table
shows the result of sequence of deque operations.
Data Structures Using C | Sudheer Kumar Kasulanati
50

09. Write about ‘Priority Queues’.

Priority queues:

 In priority queues, elements are inserted into the queue based on priority.
 Whenever we are inserting new element, it is compared with all elements in the queue & will be
inserted at proper position.
 In a priority queue, an element with highest priority is served before an element with low priority.

Example:
 In the following example, elements are given priority based on ascending order (highest number
given more priority than lowest number).

Priority Queue operations:


A priority queue supports following operations.
insert(item, priority) : Inserts an item with given priority.
getHighestPriority() : Returns the highest priority item.
deleteHighestPriority() : Removes the highest priority item.
size() : return the number of items in priority queue
isEmpty() : return whether priority queue has no items

Applications of Priority Queue:


1) CPU Scheduling
2) Graph algorithms: Dijkstra’s shortest path algorithm, Prim’s Minimal Spanning Tree etc.
3) All queue applications where priority is involved.
4) Patients in an emergency room.

Data Structures Using C | Sudheer Kumar Kasulanati


51

UNIT 4
Searching & Sorting

01. Linear [or] Sequential Search.

Searching:

 Searching is the process of finding some particular element in the list.


 If the element is present in the list, then the process is called successful and the process returns the location
of that element, otherwise the search is called unsuccessful.
 There are three popular search methods that are widely used in order to search some item in the list.
However, choice of the algorithm depends upon the arrangement of the list.

Linear Search *** Binary Search *** Indexed Sequential Search

Linear search (or) Sequential search:

 Linear search is a very basic and simple search algorithm.


 In Linear search, we search an element or value in a given array by traversing the array from the starting, till
the desired element or value is found.
 Linear search is mostly used to search an unordered list in which the items are not sorted. The algorithm of
linear search is given as follows.

Ex: In the below example, the search element 20 is found at index 6

Algorithm:

Step 1: START
Step 2: declare variables i, n , x, A[]
Step 3: initialize i  0
Step 4: Repeat steps until (i < n)
if (A[i]=x){
display “Element found at index i”
goto Step 6
}
i  i+1
Step 5: display “Element not found”
Step 6: STOP

Data Structures Using C | Sudheer Kumar Kasulanati


52

C Program to search element using Linear Search:

#include<stdio.h>
void main(){
int i,n,x,a[10];
printf("Enter the Number of elements in the Array ");
scanf("%d",&n);
printf("Enter the elements in the Array");
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
printf("Enter the element to search");
scanf("%d",&x);
for(i=0;i<n;i++){
if(a[i]==x){
printf("Element found at index %d",i);
break;
}
}
if(i==n){
printf("Element not found ");
}
}

Output:

Enter the Number of elements in the Array


5
Enter the elements in the Array
34 56 21 67 80
Enter the element to search
67
Element found at index 3

02. Binary Search.

Binary Search:

 Search a sorted array by repeatedly dividing the search interval in half.


 Begin with an interval covering the whole array.
 If the value of the search key is less than the item in the middle of the interval, narrow the interval to the
lower half.
 Otherwise narrow it to the upper half. Repeatedly check until the value is found or the interval is empty.

Example:

Data Structures Using C | Sudheer Kumar Kasulanati


53

Algorithm:

Step 1: START
Step 2: declare variables i, n , x, A[], first, last, middle
Step 3: initialize first  0, last  n-1, middle  (first+last)/2
Step 4: Repeat steps until (first<=last)
if (A[middle]=x){
display “Element found at index middle”
goto Step 6
}
else if(A[middle]<x) first  middle+1
else if(A[middle]>x) last  middle-1
middle  (first+last)/2
Step 5: display “Element not found”
Step 6: STOP

Program to Search element using Binary search:

#include<stdio.h>
void main() {
int c, first, last, middle, n, search, array[10];
printf("Enter number of elements");
scanf("%d",&n);
printf("Enter the elements");
for (c = 0; c < n; c++)
scanf("%d",&array[c]);
printf("Enter value to search");
scanf("%d",&search);
first = 0;
last = n - 1;
middle = (first + last)/2;
while( first <= last ){
if ( array[middle] == search ){
printf("Element found at index %d",middle);
break;
}
else if ( array[middle] < search ) first = middle + 1;
else last = middle - 1;
middle = (first + last)/2;
}
if ( first > last )
printf("Element not found");
}

Output:

Enter number of elements


10
Enter the elements
2 5 8 12 16 23 38 56 72 91
Enter value to search
23
Element found at index 5

Data Structures Using C | Sudheer Kumar Kasulanati


54

03. Indexed Sequential Search.

Indexed Sequential Search:

 It is a technique to improve search efficiency for a sorted list of elements.


 It requires more memory space to store index table.
 The elements in the index & elements in the given list must be in sorted order.
 Indexed Sequential Search is based on Sequential & Random access searching method.
 It search the element according to groups.

Steps:

 Step 1: Read the search element from the user.


 Step 2: Divide the array into groups according to group size.
 Step 3: Create index array that contains starting index of groups.
 Step 4: If group is present & first element of group is less than or equal to key element goto next group
Else apply linear search in previous group.
 Step 5: Repeat step 4 for all groups.

Example 1:

 In the following array of elements, we are searching for 28.

 There are 9 elements, so divide the list into 3 groups of 3 elements each.
 Starting indices of these 3 groups are 0, 3, 6. Create index array with these elements as shown below.

 Now compare first element of the first group with search element. 12<28. Goto next group.
 First element of the next group, 21<28. Goto next group.
 First element of the next group, 57>28. So apply linear search in previous group.
 21!=28, Goto next element 28=28. So display element found.

Example 2:

 In the following array of elements, we are searching for 19.

 There are 9 elements, so divide the list into 3 groups of 3 elements each.
 Starting indices of these 3 groups are 0, 3, 6. Create index array with these elements as shown below.

 Now compare first element of the first group with search element. 12<19. Goto next group.
 First element of the next group, 21>19. So apply linear search in previous group.
 12!=19, Goto next element 15!=19. Goto next element 17!=19. So display element not found.

Data Structures Using C | Sudheer Kumar Kasulanati


55

04. Bubble Sort.

Bubble Sort:

 Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they
are in wrong order.
 It is called bubble sort because the larger element bubbles up towards the last place.
 After each iteration, one element will be sorted.

Example:

 In the above example, After first iteration, the largest element 6 is placed in the last position.
 After second iteration, the largest element in the remaining list 5 is placed before 6.
 This process continues until all the elements are placed in their correct positions.

Algorithm:

Step 1: START
Step 2: declare variables i, j, temp, A[]
Step 3: initialize values i4, j0
Step 4: Read 5 elements from the user
Step 5: Repeat until (i>0)
Repeat until (j<i)
if (A[j]>A[j+1]) swap A[j] and A[j+1]
jj+1
ii-1
Step 6: display sorted elements
Step 7: STOP

Data Structures Using C | Sudheer Kumar Kasulanati


56

C Program to sort elements using Bubble Sort:

#include<stdio.h>
void main(){
int i, j,temp;
int A[5];
printf("Enter any 5 elements to sort\n");
// To read elements
for(i=0;i<5;i++)
scanf("%d",&A[i]);
// Bubble sort logic
for (i=4;i>0;i--)
for (j=0;j<i;j++)
if (A[j]>A[j+1]){
temp=A[j];
A[j]=A[j+1];
A[j+1]=temp;
}
// To display sorted elements
printf("\nElements after sorting\n");
for(j=0;j<5;j++)
printf("%d ",A[j]);
}

Output:
Enter any 5 elements to sort
34 51 20 15 37
Elements after sorting
15 20 34 37 51

05. Insertion Sort.

Insertion Sort:

 Insertion sort is a sorting algorithm which sorts the elements in the list by shifting them one by one.
 In Insertion sort, a group of items is partially sorted at any given point of time, where as in Bubble sort &
Selection sort, a group of items is fully sorted at any given point of time.
 In Insertion sort algorithm, we pick a key element, compare it with the elements before it & insert the key in
the right place.
 If there are N number of elements, After N-1 steps we will find the sorted list.

Example:

Data Structures Using C | Sudheer Kumar Kasulanati


57

 In the above example, we have 6 elements in the list. So will get the sorted list in 5 steps.

Algorithm:

Step 1:
START
Step 2:
declare variables i, j, temp, A[]
Step 3:
initialize values i1, ji-1
Step 4:
Read 5 elements from the user
Step 5:
Repeat until (i<5)
tempA[i]
Repeat until (j>=0)
if (A[j]>=temp) A[j+1] = A[j];
else break;
jj-1
A[j+1]temp
ii+1
Step 6: display sorted elements
Step 7: STOP

C Program to sort elements using Insertion Sort:

#include<stdio.h>
void main(){
int i, j, temp;
int A[5];
printf("Enter any 5 elements to sort\n");
// Read Elements
for(i=0;i<5;i++)
scanf("%d",&A[i]);
// Insertion Sort logic
for(i=1; i<5; i++) {
temp = A[i];
for (j=i-1;j>=0;j--)
if (A[j]>=temp) A[j+1] = A[j];
else break;
A[j+1] = temp;
} // end for
// display sorted elements
printf("\nElements after sorting\n");
for(j=0;j<5;j++)
printf("%d ",A[j]);
}

Output:
Enter any 5 elements to sort
34 51 20 15 37
Elements after sorting
15 20 34 37 51

Data Structures Using C | Sudheer Kumar Kasulanati


58

06. Selection Sort.

Selection Sort:

 Selection Sort algorithm first finds the smallest element in the list and swaps it with the element in
the first position, then finds the second smallest element and exchange it with the element in the
second position, and continues in this way until the entire list is sorted.
 If we want to sort the elements in descending order, we can do the same above procedure by taking
biggest number instead of smallest number.

Example:

 In the above example, there are total 6 elements in the list. So we will get the sorted list after 5
 iterations.
 In first iteration, 1 is the smallest element. So 1 is placed in the first position after swapping with 3.
 In second iteration, 3 is smallest element. So 3 is placed in the second position after swapping with 6.
 In third iteration, 4 is smallest element. So 4 is placed in the third position after swapping with 6.
 In fourth iteration, 5 is smallest element. So 5 is placed in the fourth position after swapping with 8.
 In fifth iteration, 6 is the smallest number which is in fifth position. So, no need to swap.
 After fifth iteration, all the elements will be in sorted order.

Algorithm:

Step 1: START

Step 2: declare variables i, j, temp, min, A[]

Step 3: initialize values i0, ji+1

Step 4: Read 5 elements from the user

Step 5: Repeat until (i<4)


min  i
Repeat until (j<5)
if (A[j]<A[min]) minj
j  j+1
swap A[i] and A[min]
i  i+1
Step 6: display sorted elements

Step 7: STOP

Data Structures Using C | Sudheer Kumar Kasulanati


59

C program to sort elements using Selection sort:

#include<stdio.h>
void main(){
int i,j, temp, min;
int A[5];
for(i=0;i<5;i++){
scanf("%d",&A[i]);
}
//Selection_Sort logic
for (i=0;i<4;i++){
min = i;
for (j=i+1;j<5;j++)
if (A[j]<A[min]) min = j;
temp = A[i];
A[i]=A[min];
A[min]=temp;
}
// display sorted elements
for(j=0;j<5;j++)
printf("%d ",A[j]);
}

Output:
26 67 32 11 54
11 26 32 54 67

Data Structures Using C | Sudheer Kumar Kasulanati


60

07. Merge Sort.

Merge Sort:

 Merge sort is a “divide and conquer” algorithm wherein we first divide the problem into sub problems. When
the solutions for the sub problems are ready, we combine them together to get the final solution to the
problem.

 This is one of the algorithms which can be easily implemented using recursion as we deal with the sub
problems rather than the main problem.

 The algorithm can be described as the following 2 step process:

Divide: In this step, we divide the input array into 2 halves, the pivot being the midpoint of the array. This
step is carried out recursively for all the half arrays until there are no more half arrays to divide.

Conquer: In this step, we sort and merge the divided arrays from bottom to top and get the sorted array.

Algorithm:

MergeSort(A[], low, high)

Step 1: N = high-low
Find the middle point to divide the array into two halves:
mid = low +N/2
Step 2: call mergeSort for first half:
call mergeSort(A, low, mid)
Step 3: call mergeSort for second half:
call mergeSort(A, mid, high)
Step 4: Merge the two halves sorted in step 2 and 3:

Example: Given elements: 38 43 27 12 25 8

Data Structures Using C | Sudheer Kumar Kasulanati


61

C Program to sort elements using Merge Sort:

#include<stdio.h>
void sort(int[], int, int);
void main(){
int i, n, a[10];
printf("Enter number of elements...");
scanf("%d",&n);
printf("Enter the elements...");
// to read elements
for (i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,0,n);
// to display sorted elements
printf("Elements after sorting…");
for (i=0;i<n;i++)
printf("%d ",a[i]);
}

void sort(int a[], int low, int high){


int N, mid, temp[10], i, j, k;
N = high-low;
if(N<=1) return;
mid = low +N/2;
sort(a, low, mid);
sort(a, mid, high);
i=low, j=mid;
for(k=0;k<N;k++){
if (i==mid) temp[k]=a[j++];
else if (j==high) temp[k]=a[i++];
else if (a[j]<a[i]) temp[k]=a[j++];
else temp[k]=a[i++];
}
for (k=0; k<N; k++)
a[low+k]=temp[k];
}

Output:

Enter number of elements...


5
Enter the elements...
34 51 20 15 37
Elements after sorting…
15 20 34 37 51

Data Structures Using C | Sudheer Kumar Kasulanati


62

08. Quick Sort.

Quick Sort:

 Quick sort algorithm is very fast & requires less additional space.
 This algorithm is based on the rule ‘Divide and Conquer’. This is also called partition exchange sort.
 This algorithm divides the list into 3 main parts:
 Elements less than pivot element.
 Pivot element.
 Elements greater than pivot element.

Selecting the pivot:

 We can select the pivot element in different ways:

 pick first element as pivot.


 pick last element as pivot (implemented below)
 pick a random element as pivot.
 pick median as pivot.

Quick Sort Algorithm

Using this algorithm recursively, we end up with smaller possible partitions. Each partition is then
processed for quick sort. We define recursive algorithm for quicksort as follows −

Step 1 − Make the right-most index value pivot


Step 2 − partition the array using pivot value
Step 3 − quicksort left partition recursively
Step 4 − quicksort right partition recursively

Quick Sort Partition Algorithm

Following are the steps to follow, when we want to partition in quick sort.

Step 1 − Choose the highest index value has pivot


Step 2 − Take variables to point left of the list
Step 3 − left points to the low index
Step 4 − while value at left is less than pivot move right
Step 6 − while value at left is greater than pivot move left to the right side of pivot
Step 7 – now pivot element is at correct index.
Step 8 – return pivot index.

Example:

 In the above example, after partition the pivot element 25 is in its correct position.

Data Structures Using C | Sudheer Kumar Kasulanati


63

 Now consider 6,8,17,14 & 37,52, 63 as two separate groups and apply the same logic to partition.
 This process continues until all the elements are sorted.

C program to sort elements using Quick sort:

#include<stdio.h>
int A[5] = {12, 45, 10, 67, 18};
void display(){
for(int j=0;j<5;j++)
printf("%d ",A[j]);
}
void swap(int m, int n){
int temp = A[m];
A[m] = A[n];
A[n] = temp;
}

int partition(int low, int high, int pivot){


while (low<high)
if (A[low]>=pivot){
swap(low, high-1);
swap(high-1, high);
high--;
}
else low++;
return high;
}

void QSort(int left, int right){


if (left<right){
int pivot = A[right];
int pivot_index = partition(left,right,pivot);
QSort(left,pivot_index-1);
QSort(pivot_index+1, right);
}
}

void main(){
display();
QSort(0,4);
printf("\n");
display();
}

Output:
12 45 10 67 18
10 12 18 45 67

Data Structures Using C | Sudheer Kumar Kasulanati


64

Data Structures Using C | Sudheer Kumar Kasulanati


65

UNIT 5
Trees & Graphs

01. Binary tree ADT – Types & Representation.

Binary Trees:
 A binary tree is a special type of tree in which every node or vertex has maximum of two child
nodes.
 Child node in a binary tree on the left is termed as 'left child node' and node in the right is
termed as the 'right child node'.
 In the below figure, the root node 8 has two children 3 and 10.
 The left child node 3 acts as parent node for 1 & 6. The right child node 10 acts as parent node
for 14.
 Similarly, 6 has child nodes 4 & 7. 14 has child node 13.

A binary tree may also be defined as follows:

 A binary tree is either an empty tree Or a binary tree consists of a node called the root node, a
left subtree and a right subtree, both will act as a binary tree once again.
 A binary tree node contains following parts:
 data
 pointer to left child
 pointer to right child

 The top most node in the tree is called the root. An empty tree is represented by NULL pointer.

Data Structures Using C | Sudheer Kumar Kasulanati


66

A representation of binary tree is shown below:

Binary Tree: Common Terminologies

Root : Topmost node in a tree.

Parent : Every node (excluding a root) in a tree is connected by a


directed edge from exactly one other node. This node is called a
parent.

Child : A node directly connected to another node when moving away


from the root.

Leaf/External node : Node with no children.

Internal node : Node with atleast one children.

Depth of a node : Number of edges from root to the node.

Height of a node : Number of edges from the node to the deepest leaf.
Height of the tree is the height of the root.

Data Structures Using C | Sudheer Kumar Kasulanati


67

 In the above binary tree, the root node is A.


 The tree has 10 nodes with 5 internal nodes and 5 external nodes.
 In the above tree, internal nodes are : A, B, C, D, F
 In the above tree, external nodes are : H, I, E, J, G
 The height of the tree is 3.

Advantages of Trees:

 Trees reflect structural relationships in the data.


 Trees are used to represent hierarchies.
 Trees provide an efficient insertion & searching.
 Trees are very flexible, so we can move subtrees with minimum effort.

Types of Binary trees:


 Based on the structure, binary trees can be classified into 3 types:
 These are: Full Binary Tree, Perfect Binary Tree & Complete Binary Tree.

Full Binary Tree:

 It is a binary tree in which every node in the tree has either 0 or 2 children.
 The below shown tree is full binary tree.

 The number of leaf nodes in a full binary tree = number of internal nodes + 1
 In the above example, there are 4 internal nodes, so leaf nodes are 4+1 = 5.

Perfect Binary Tree:

 It is a binary tree in which all internal nodes have two children and all leaves are at same level.

 In a perfect binary tree, the number of nodes N = 2L-1, Here L = Number of Leaf nodes

Data Structures Using C | Sudheer Kumar Kasulanati


68

 In a perfect binary tree, the number of leaf nodes L = 2H, Here H = Height of the tree
 In a perfect binary tree, the number of nodes N = 2H +L-1

Complete Binary Tree:

 It is a binary tree in which every level except the last, is completely filled and all nodes are as
far left as possible.

 The number of internal nodes in a complete binary tree = N/2, Here N is total number of nodes.
 In the above example, N = 6, So the number of internal nodes = 6/2 = 3

Representation of Binary trees:


There are two types of representation of a binary tree:

1. Linked Representation

 In this representation, the binary tree is stored in the memory, in the form of a linked list where
the number of nodes are stored at non-contiguous memory locations and linked together by
inheriting parent child relationship like a tree.
 Each node contains three parts : pointer to the left node, data element and pointer to the
right node.
 Each binary tree has a root pointer, which points to the root node of the binary tree.
 In an empty binary tree, the root pointer will point to null.
 Consider the binary tree given in the figure below.

 In the above figure, a tree is seen as the collection of nodes where each node contains three
parts : left pointer, data element and right pointer. Left pointer stores the address of the left
child while the right pointer stores the address of the right child.
Data Structures Using C | Sudheer Kumar Kasulanati
69

 The leaf node contains null in its left and right pointers.
 The following image shows about how the memory will be allocated for the binary tree by using
linked representation.
 There is a special pointer maintained in the memory which points to the root node of the tree.
Every node in the tree contains the address of its left and right child. Leaf node contains null in
its left and right pointers.

2. Sequential Representation

 This is the simplest memory allocation technique used to store the tree elements.
 It is an inefficient technique since it requires a lot of space to store the tree elements.
 A binary tree is shown in the following figure along with its memory allocation.

 In this representation, an array is used to store the tree elements. Size of the array will be
equal to the number of nodes present in the tree.

The root node of the tree will be present at the 1st index of the array. If a node is stored at i th
index then its left and right children will be stored at 2i and 2i+1 location.

Data Structures Using C | Sudheer Kumar Kasulanati


70

02. Write about properties of Binary trees.

Binary tree:

 Binary tree is a special tree data structure.


 In a binary tree, each node can have at most 2 children.
 Following are the important properties of binary trees:

Property 01: Minimum number of nodes in a binary tree of height H is H + 1

Ex: To construct a binary tree of height = 4, we need at least 4 + 1 = 5 nodes.

Property 02: Maximum number of nodes in a binary tree of height H is 2H+1 – 1

Example: Maximum number of nodes in a binary tree of height 3 = 23+1 – 1


= 16 – 1
= 15 nodes

So, in a binary tree of height = 3, maximum number of nodes that can be inserted = 15.

Data Structures Using C | Sudheer Kumar Kasulanati


71

Property 03: Total Number of leaf nodes in a Binary Tree = Total Number of nodes with 2

children + 1

Ex: Consider the following binary tree.

 In the above binary tree, number of leaf nodes is 3 & number of nodes with 2 children is 2, So
Total Number of leaf nodes in a Binary Tree = Total Number of nodes with 2 children + 1

Property 04: Maximum number of nodes at any level ‘L’ in a binary tree = 2L

Ex: Maximum number of nodes at level-2 in a binary tree = 22 = 4


So, in a binary tree, maximum number of nodes that can be present at level-2 = 4.

03. Binary trees – Traversal techniques (In-order, Pre-order, Post-order).

Binary Tree Traversal Techniques:

There are three ways to traverse a Binary Tree : in-order, pre-order & post-order traversals.

In-order Traversal: Following are the steps for Inorder traversal:

Step 1: Traverse the Node’s left subtree.


Step 2: Visit the Node.
Step 3: Traverse the Node’s right subtree.

C code for Inorder traversal:

void inOrder(node localRoot) {


if(localRoot != null) {
inOrder(localRoot.leftChild);
localRoot.display();
inOrder(localRoot.rightChild);
}
}
This method is initially called with the root as an argument: inOrder(root);
Data Structures Using C | Sudheer Kumar Kasulanati
72

Ex:

For the above tree, Inorder traversal is:


G-D- H-B-E-A-C-I-F-J

Pre-order Traversal:

In Pre-order traversal of a Binary Tree, data will be visited first, then left & right subtrees will be
visited.

Following are the steps for Preorder traversal:


Step 1: Visit the Node.
Step 2: Traverse the node’s left subtree.
Step 3: Traverse the node’s right subtree.

C code for Preorder traversal:

void preOrder(node localRoot) {


if(localRoot != null) {
localRoot.display();
preOrder(localRoot.leftChild);
preOrder(localRoot.rightChild);
}
}
This method is initially called with the root as an argument: preOrder(root);
Ex:

For the above tree, Preorder traversal is:


A-B- D-G-H-E-C-F-I–J

Post-order Traversal:

An Post-order traversal of a Binary Tree, after visiting left & right subtrees, data will be visited.
Following are the steps for Postorder traversal:
Step 1: Traverse the node’s left subtree.
Step 2: Traverse the node’s right subtree.
Step 3: Visit the Node.

Data Structures Using C | Sudheer Kumar Kasulanati


73

C code for Postorder traversal:

void postOrder(node localRoot) {


if(localRoot != null) {
postOrder(localRoot.leftChild);
postOrder(localRoot.rightChild);
localRoot.display();
}
}
This method is initially called with the root as an argument: postOrder(root);
Ex:

For the above tree, Postorder traversal is:


G-H- D-E-B-I-J-F-C–A

04. BST (Binary Search Tree) operations.

Binary Search Tree


1. Binary Search tree can be defined as a class of binary trees, in which the nodes are arranged in a
specific order. This is also called ordered binary tree.
2. In a binary search tree, the value of all the nodes in the left sub-tree is less than the value of the root.
3. Similarly, value of all the nodes in the right sub-tree is greater than or equal to the value of the root.
4. This rule will be recursively applied to all the left and right sub-trees of the root.

Data Structures Using C | Sudheer Kumar Kasulanati


74

 A Binary search tree is shown in the above figure. As the constraint applied on the BST, we can see that
the root node 30 contain all values less than 30 in its left sub-tree and contain all values greater than 30
in its right sub-tree.

Advantages of using binary search tree

1. Searching become very efficient in a binary search tree since, we get a hint at each step, about
which sub-tree contains the desired element.
2. The binary search tree is considered as efficient data structure in compare to arrays and linked
lists. In searching process, it removes half sub-tree at every step.
3. It also speed up the insertion and deletion operations as compare to that in array and linked
list.

Construction of BST:

Following are the steps to construct a Binary tree:

Step 1: Insert the first element as the root of the tree.


Step 2: Read the next element.
Step 3: If it is less than the root element, insert it as the root of left sub-tree.
Step 4: Otherwise, insert it as the root of the right sub-tree.
Step 5: Repeat steps 2,3 and 4 for all the elements.

Example: Create the BST using the following data elements: 43, 10, 79, 90, 12, 54, 11, 9, 50

The process of creating BST by using the given elements, is shown in the image below.

STEP 1 STEP 2 STEP 3

STEP 4 STEP 5 STEP 6

Data Structures Using C | Sudheer Kumar Kasulanati


75

STEP 7 STEP 8 STEP 9

Operations on Binary Search Tree


There are many operations which can be performed on a binary search tree.

SNo Operation Description

1 Searching in Finding the location of some specific element in a binary search tree.
BST

2 Insertion in Adding a new element to the binary search tree at the appropriate location
BST so that the property of BST do not violate.

3 Deletion in Deleting some specific node from a binary search tree. However, there can
BST be various cases in deletion depending upon the number of children, the
node have.

Searching in BST:

 To search a given key in Binary Search Tree, we first compare it with root, if the key is present
at root, we return root.
 If key is greater than root’s key, we follow the same process for right subtree of root node.
Otherwise we follow the same process for left subtree.

C code for searching in BST:

Node search(Node root, int key){


// Base Cases: root is null or key is present at root
if (root==null || root==key)
return root;
if (key > root)
return search(root.right, key);
else
return search(root.left, key);
}

Data Structures Using C | Sudheer Kumar Kasulanati


76

Example: Search for 54 in below BST:

1. Start from the root 43. 54 is greater than 43 so we recur right sub-tree.
2. Now, 54 is less than 79, so we recur left sub-tree.
3. Now, 54 is equal to 54. So element is found in the BST.

Insert element in BST:

 In a BST, A new element is always inserted at leaf.


 We start searching a key from root till we hit a leaf node.
 Once a leaf node is found, the new node is added as a child of the leaf node.

Example:

C code to insert new element in BST:

Node insertRec(Node root, int key) {


/* If the tree is empty, return a new node */
if (root == null) {
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root)
root.left = insertRec(root.left, key);
else if (key > root)
root.right = insertRec(root.right, key);
return root;
}

Data Structures Using C | Sudheer Kumar Kasulanati


77

Delete element in BST:

When we delete a node, three possibilities arise.

1) Node to be deleted is leaf: Simply remove the node from the tree.

2) Node to be deleted has only one child: Copy the child to the node and delete the child.

3) Node to be deleted has two children: Find inorder successor of the node. Copy contents of
the inorder successor to the node and delete the inorder successor. Note that inorder predecessor
can also be used.

05. Applications of Binary Trees [or] Threaded Binary Trees.

Threaded Binary Trees:

 Threaded Binary Tree is also a binary tree in which all left child pointers that are NULL (in Linked
list representation) points to their in-order predecessor, and all right child pointers that are NULL
(in Linked list representation) points to their in-order successor.
 A binary tree can be represented using array representation or linked list representation. When a
binary tree is represented using linked list representation, the reference part of the node which
doesn't have a child is filled with a NULL pointer.
 In any binary tree linked list representation, there is a number of NULL pointers than actual
pointers.
 Generally, in any binary tree linked list representation, if there are 2N number of reference fields,
then N+1 number of reference fields are filled with NULL.

Data Structures Using C | Sudheer Kumar Kasulanati


78

 This NULL pointer does not play any role except indicating that there is no link (no child).
 A. J. Perlis and C. Thornton have proposed new binary tree called "Threaded Binary Tree",
which makes use of NULL pointers to improve its traversal process.
 In a threaded binary tree, NULL pointers are replaced by references of other nodes in the tree.
These extra references are called as threads.
 If there is no in-order predecessor or in-order successor, then it points to the root node.

 Consider the following binary tree...

 To convert the above example binary tree into a threaded binary tree, first find the in-order
traversal of that tree.
 In-order traversal of above binary tree: H - D - I - B - E - A - F - J - C – G
 When we represent the above binary tree using linked list representation, nodes H, I, E, F,
J and G left child pointers are NULL. This NULL is replaced by address of its in-order predecessor
respectively (I to D, E to B, F to A, J to F and G to C), but here the node H does not have its in-
order predecessor, so it points to the root node A.
 The nodes H, I, E, J and G right child pointers are NULL. These NULL pointers are replaced by
address of its in-order successor respectively (H to D, I to B, E to A, and J to C), but here the node
G does not have its in-order successor, so it points to the root node A.

 Above example binary tree is converted into threaded binary tree as follows.

In the above figure, threads are indicated with dotted links.

Data Structures Using C | Sudheer Kumar Kasulanati


79

06. Graphs – Representation.

Graph
 A graph can be defined as group of vertices and edges that are used to connect these vertices.
 A graph can be seen as a cyclic tree, where the vertices (Nodes) maintain any complex relationship among
them instead of having parent child relationship.

Definition

 A graph G can be defined as an ordered set G(V, E) where V(G) represents the set of vertices and E(G)
represents the set of edges which are used to connect these vertices.
 A Graph G(V, E) with 5 vertices (A, B, C, D, E) and six edges ((A,B), (B,C), (C,E), (E,D), (D,B), (D,A)) is
shown in the following figure.

A B C
A A
D E
A

Types of Graphs:

 A graph can be undirected or directed.


 In an undirected graph, edges are not associated with the directions with them.
 If an edge exists between vertex A and B then the vertices can be traversed from A to B as well as B to A.
 An undirected graph is shown in the below figure since its edges are not attached with any of the
directions.

A B C
A A
D E
A
Undirected Graph

 In a directed graph, edges form an ordered pair.


 Edges represent a specific path from some vertex A to another vertex B. Node A is called initial node while
node B is called terminal node.
 A directed graph is shown in the following figure.

A B C
A A
D E
A
Directed Graph

Data Structures Using C | Sudheer Kumar Kasulanati


80

Graph Terminology
Path

A path can be defined as the sequence of nodes that are followed in order to reach some terminal node V from the
initial node U.

Closed Path

A path will be called as closed path if the initial node is same as terminal node. A path will be closed path if V 0=VN.

Simple Path

If all the nodes of the graph are distinct with an exception V0=VN, then such path P is called as closed simple path.

Cycle

A cycle can be defined as the path which has no repeated edges or vertices except the first and last vertices.

Connected Graph

A connected graph is the one in which some path exists between every two vertices (u, v) in V. There are no
isolated nodes in connected graph.

Complete Graph

A complete graph is the one in which every node is connected with all other nodes. A complete graph contain

n(n-1)/2 edges where n is the number of nodes in the graph.

If the number of nodes is 4, then there will be 4(4-1)/2 = 6 edges.

If the number of nodes is 5, then there will be 5(5-1)/2 = 10 edges.

Weighted Graph

In a weighted graph, each edge is assigned with some data such as length or weight. The weight of an edge e can
be given as w(e) which must be a positive (+) value indicating the cost of traversing the edge.

Digraph:

A digraph is a directed graph in which each edge of the graph is associated with some direction and the traversing
can be done only in the specified direction.

Adjacent Nodes

If two nodes u and v are connected via an edge e, then the nodes u and v are called as neighbours or adjacent
nodes.

Degree of the Node

A degree of a node is the number of edges that are connected with that node. A node with degree 0 is called as
isolated node.

Data Structures Using C | Sudheer Kumar Kasulanati


81

Graph Representation
 Graph representation is the technique which is to be used in order to store some graph into the computer's
memory.
 There are two ways to store Graph into the computer's memory.

Sequential Representation

 In sequential representation, we use adjacency matrix to store the mapping represented by vertices and
edges.
 In adjacency matrix, the rows and columns are represented by the graph vertices.
 A graph having n vertices, will have a dimension n x n.
 An entry Mij in the adjacency matrix representation of an undirected graph G will be 1 if there exists an
edge between Vi and Vj.
 An undirected graph and its adjacency matrix representation is shown in the following figure.

 in the above figure, we can see the mapping among the vertices (A, B, C, D, E) is represented by using
the adjacency matrix which is also shown in the figure.
 There exists different adjacency matrices for the directed and undirected graph. In directed graph, an

entry Aij will be 1 only when there is an edge directed from Vi to Vj.
 A directed graph and its adjacency matrix representation is shown in the following figure.

Data Structures Using C | Sudheer Kumar Kasulanati


82

 Representation of weighted directed graph is different. Instead of filling the entry by 1, the Non- zero
entries of the adjacency matrix are represented by the weight of respective edges.
 The weighted directed graph along with the adjacency matrix representation is shown in the following
figure.

Linked Representation

 In the linked representation, an adjacency list is used to store the Graph into the computer's memory.
 Consider the undirected graph shown in the following figure and check the adjacency list representation.

 An adjacency list is maintained for each node present in the graph which stores the node value and a
pointer to the next adjacent node to the respective node.
 If all the adjacent nodes are traversed then store the NULL in the pointer field of last node of the list.
 The sum of the lengths of adjacency lists is equal to the twice of the number of edges present in an
undirected graph.
 In the above example, Number of edges is 6 and sum of lengths in adjacency list is 12.
 Consider the directed graph shown in the following figure and check the adjacency list representation of
the graph.

Data Structures Using C | Sudheer Kumar Kasulanati


83

 In a directed graph, the sum of lengths of all the adjacency lists is equal to the number of edges present in
the graph.
 In the above example, the number of edges is 6 & the sum of lengths is 6.
 In the case of weighted directed graph, each node contains an extra field that is called the weight of
the node. The adjacency list representation of a directed graph is shown in the following figure.

07. Graphs – Traversals (searching techniques) : DFS & BFS

Graph Traversal Algorithms


Traversing the graph means examining all the nodes and vertices of the graph. There are two standard methods
by using which, we can traverse the graphs.

 Depth First Search (DFS)


 Breadth First Search (BFS)

DFS (Depth First Search) algorithm:

The DFS algorithm uses a stack to remember where it should go when it reaches dead end.

Ex:

Data Structures Using C | Sudheer Kumar Kasulanati


84

Implementing DFS method:

Select a starting point, In the above example, we selected ‘A’. Follow the rules mentioned below.

Rule1 : If possible, visit an adjacent unvisited vertex, mark it, push it on the stack.

Rule 2: If you can’t follow Rule 1, then if possible, pop the vertex from stack.

Rule 3: If you can’t follow Rule 1 (or) Rule 2, then you are finished.

Following are the stack contents during DFS:

BFS (Breadth First Search) algorithm:

In BFS, all the adjacent vertices are visited first, then goes for remaining vertices.

Ex:

Data Structures Using C | Sudheer Kumar Kasulanati


85

Implementing BFS method:

Select a starting point, In the above example, we selected ‘A’. Make it current vertex & follow the rules
mentioned below.

Rule1: Visit the next unvisited vertex, that is adjacent to the current vertex. Mark it & insert into the
queue.

Rule 2: If you can’t follow Rule 1 (There is no unvisited vertex), Remove a vertex from the queue &
make it the current vertex.

Rule 3: If you can’t follow Rule 2 (queue is empty), you are finished.

Queue contents during BFS:

08. MST (Minimal Spanning Trees).

Minimal Spanning Tree (MST) – Kruskal’s Algorithm:

 The MST connects all the vertices with minimum number of edges & with minimum
weightage.
 If there are ‘n’ number of vertices in a graph, then the minimum number of edges will
be ‘n-1’.
 Following figure is a graph of 7 vertices.

Data Structures Using C | Sudheer Kumar Kasulanati


86

 The edges & weights for the above graph are shown below.

Following are the steps to get MST:

Step 1:
Find the edge, which is having minimum weight. In the above example, the edge ‘AC’ is having
minimum weight (5).

Step 2:
Find the minimum in remaining edges. (Make sure that whenever we select an edge, it should not
form cycle with already selected edges).
In the above example, select BD (7), FG (9), CD (13), EG (14) & BE (15).

Step 3: Keep on selecting edges until all vertices are connected.


The MST for the above graph will be as shown below.

Data Structures Using C | Sudheer Kumar Kasulanati


87

09. Applications of Graphs [or] Connected components of Graphs.

Connected Components of Graphs:


 In graph theory, a component, sometimes called a connected component, of an undirected
graph is a subgraph in which any two vertices are connected to each other by paths, and which
is connected to no additional vertices in the supergraph.
 A connected component of a graph is a maximal subgraph in which the vertices are all
connected, and there are no connections between the subgraph and the rest of the graph.
 A connected graph has only one connected component, which is the graph itself, while
unconnected graphs have more than one component.
 For example, the graph shown below has three components:
(0, 1, 2, 3), (4, 5, 6), and (7, 8).

 The connected components of a graph can be found using either a depth-first search (DFS), or a
breadth-first search (BFS).
 We start at an arbitrary vertex, and visit every vertex adjacent to it recursively, adding them to
the first component.
 Once this search has finished, we have visited all of the vertices in the first connected
component, so we choose another unvisited vertex (if any) and perform the same search
starting from it, adding the vertices we find to the second component.
 This process continues until all vertices have been visited, at which point we know the number
of connected components in the graph, and which vertices they contain.

Process to count Number of connected components in an undirected graph:

 Given an undirected graph g, the task is to print the number of connected components in the
graph.

Data Structures Using C | Sudheer Kumar Kasulanati


88

Approach: The idea is to use a variable count to store the number of connected components
and do the following steps:

Step 1: Initialize all vertices as unvisited.


Step 2: For all the vertices check if a vertex has not been visited, then perform
DFS on that vertex and increment the variable count by 1.

Connected components in a directed graph:

 There are two types of connected components in directed graph: strongly connected and weakly
connected components.
 A directed graph is said to be strongly connected if from any node there’s always a path to
reach any other one. This is the criterion city roads should be designed with.

Example 1: As we can see, In the below component, all nodes can be reached from any
other node. So it is strongly connected.

Example 2: In the below component, Since there are no paths between 3 to any other
nodes, it is not strongly connected.

 The way to check for a graph being strongly connected is doing a DFS from a starting node and
check if every other node can be reached.
 Do this process for all nodes in the component.
 If the graph is strongly connected every node will be reachable from the starting one.

Data Structures Using C | Sudheer Kumar Kasulanati


89

Model Paper 1
DATA STRUCTURES USING C
Time : Three hours Max Marks: 70M

SECTION A – (5 x 4 = 20 marks)

Answer any FIVE of the following questions.


1. Time complexity & Space complexity.
2. Big ‘O’ notation.
3. Sparse matrix.
4. Circular queues.
5. Priority queues.
6. Binary tree properties.
7. Threaded binary trees.
8. Linear search.

SECTION B – (5 x 10 = 50 marks)
Answer following questions.

UNIT 1 UNIT IV

9. Write different types of data structures? 15. Quick Sort.


(or) (or)
10. What are the characteristics of an 16. Binary Search.
algorithm?
.

UNIT II UNIT V

11. Write about Array Operations. 17. Binary trees – Traversal techniques.
(or) (or)
12. Write about single linked list & it’s 18. Graphs - Traversals.
operations.

UNIT III

13. Stacks – Arrays & Linked list


representation.
(or)

14. Queues – Arrays & Linked list


representation.

Data Structures Using C | Sudheer Kumar Kasulanati


90

Model Paper 2
DATA STRUCTURES USING C
Time : Three hours Max Marks: 70M

SECTION A – (5 x 4 = 20 marks)

Answer any FIVE of the following questions.


1. Differentiate data type & data structure.
2. Dynamic Memory Allocation in C.
3. Differentiate Array & Linked List.
4. Double Ended Queues.
5. Binary Search.
6. Binary tree properties.
7. Give examples for different types of
binary trees.
8. Threaded binary tress.

SECTION B – (5 x 10 = 50 marks)
Answer following questions.

UNIT 1 UNIT IV

9. Write about ADTs. 15. Bubble Sort.


(or) (or)
10. Array ADT operations. 16. Merge Sort.
.

UNIT II UNIT V

11. Single Linked List Operations. 17. Binary Search Tree – Operations.
(or) (or)
12. Write about Circular Linked List. 18. Minimal Spanning Trees.

UNIT III

13. Stacks – ADT operations.


(or)
14. Queues – ADT operations.

Data Structures Using C | Sudheer Kumar Kasulanati

You might also like