1st Module Data Structures
1st Module Data Structures
Introduction and Overview: Definition, Elementary data organization, Data Structures, data
Structures operations, Abstract data types, algorithms complexity, time-space trade-off.
Preliminaries: Mathematical notations and functions, Algorithmic notations, control structures,
Complexity of algorithms, asymptotic notations for complexity of algorithms. Introduction to
Strings, Storing String, Character Data Types, String Operations, word processing, Introduction
to pattern matching algorithms.
[Link]
In computer science, a data structure is a way of organizing and storing data in a computer
program so that it can be accessed and used efficiently. Data structures provide a means of
managing large amounts of data, enabling efficient searching, sorting, insertion and deletion
of data.
Elementary data organization
Data structures are the building blocks of any program or the software. Choosing the
appropriate data structure for a program is the most difficult task for a programmer.
Data: Data can be defined as an elementary value or the collection of values.
Ex: student's name and its id are the data about the student.
Group Items: Data items which have subordinate data items are called Group item.
Ex: name of a student can have first name and the last name.
Record: Record can be defined as the collection of various data items.
Ex: if we talk about the student entity, then its name, address, course and marks can be
grouped together to form the record for the student.
File: A File is a collection of various records of one type of entity.
Ex: if there are 60 employees in the class, then there will be 20 records in the related file
where each record contains the data about each employee.
Attribute and Entity: An entity represents the class of certain objects. It contains
various attributes. Each attribute represents the particular property of that entity.
Field: Field is a single elementary unit of information representing the attribute of an
Dell | [SCHOOL]
entity.
Data Structures:
Dell | [SCHOOL]
1. Array:
An array is a collection of data items stored at contiguous memory locations. The idea is to
store multiple items of the same type together. This makes it easier to calculate the position
of each element by simply adding an offset to a base value, i.e., the memory location of the
first element of the array (generally denoted by the name of the array).
2. Linked Lists:
Like arrays, Linked List is a linear data structure. Unlike arrays, linked list elements are not
stored at a contiguous location; the elements are linked using pointers.
Dell | [SCHOOL]
Stack Operations:
push(): When this operation is performed, an element is inserted into the stack.
pop(): When this operation is performed, an element is removed from the top of the stack
and is returned.
top(): This operation will return the last inserted element that is at the top without
removing it.
size(): This operation will return the size of the stack i.e. the total number of elements
present in the stack.
isEmpty(): This operation indicates whether the stack is empty or not.
4. Queue:
Like Stack, Queue is a linear structure which follows a particular order in which the
operations are performed. The order is First in First out (FIFO). In the queue, items are
inserted at one end and deleted from the other end. A good example of the queue is any queue
of consumers for a resource where the consumer that came first is served first. The difference
between stacks and queues is in removing. In a stack we remove the item the most recently
added; in a queue, we remove the item the least recently added.
Dell | [SCHOOL]
Queue Data Structure
Queue Operations:
Enqueue(): Adds (or stores) an element to the end of the queue..
Dequeue(): Removal of elements from the queue.
Peek() or front(): Acquires the data element available at the front node of the queue
without deleting it.
rear(): This operation returns the element at the rear end without removing it.
isFull(): Validates if the queue is full.
isNull(): Checks if the queue is empty.
Dell | [SCHOOL]
Arranging data in ascending or descending order.
Example: Bubble Sort (basic idea)
Time Complexity:
Worst: O(n²)
6. Merging
Combining two data structures into one.
Used in merge sort and file processing.
Characteristics of Data Structures
A data structure is a way of organizing and storing data so it can be used efficiently. The
main characteristics are explained below:
1. Linear and Non-Linear Data Structures
� Linear Data Structure
In a linear data structure, elements are arranged sequentially (one after another).
Each element (except first and last) has:
One predecessor
One successor
Examples:
Array
Linked List
Stack
Queue
Features:
Easy to implement
Easy to traverse
Memory is arranged in sequence
� Example:
10 → 20 → 30 → 40
� Non-Linear Data Structure
In a non-linear data structure, elements are not arranged sequentially.
One element can be connected to multiple elements.
Examples:
Tree
Graph
Dell | [SCHOOL]
Features:
Hierarchical structure
Complex relationships
Used in advanced applications
� Example (Tree structure):
10
/ \
20 30
Dell | [SCHOOL]
Static and Dynamic Data Structures
� Static Data Structure
Memory size is fixed at compile time
Size cannot be changed during program execution
Example:
Array
int arr[10];
Features:
Fast access
Less flexible
May waste memory
Dell | [SCHOOL]
An Abstract Data Type (ADT) is a logical description of a data type that specifies:
The set of values
The operations allowed
The behaviour of those operations
It does NOT specify how operations are implemented.
What is an Abstract Data Type (ADT)?
An Abstract Data Type (ADT) is a logical or mathematical model of a data structure that
defines:
What data is stored
What operations can be performed on the data
What the operations do
But it does NOT specify how the operations are implemented.
In simple words:
ADT tells what to do, not how to do it.
Example of ADT
Consider a Stack ADT:
It defines operations like:
push() – Insert element
Dell | [SCHOOL]
pop() – Remove top element
peek() – View top element
isEmpty() – Check if stack is empty
It does not say whether the stack is implemented using:
Array
Linked List
That implementation part is hidden.
Why is it called "Abstract" Data Type?
It is called abstract because:
It hides implementation details.
It shows only essential features.
The user does not know how internally it works.
Think of it like using an ATM machine:
You know how to withdraw money.
You don’t know how the machine processes internally.
That hidden internal working makes it abstract.
Difference between ADT and Normal Data Type
Feature Normal Data Type Abstract Data Type (ADT)
Abstraction No Yes
Example Comparison
int → Just stores a number.
Stack ADT → Stores multiple elements and defines specific operations on them.
How ADT is Different From Other Data Structures?
Data Structure = Implementation
ADT = Definition / Blueprint
Example:
Dell | [SCHOOL]
Stack (ADT) → Concept
Stack using array → Implementation
Stack using linked list → Another implementation
So ADT is like a design, and data structure is the real building.
Dell | [SCHOOL]
Algorithms complexity
Algorithm is a step by step procedure for solving a problem or accomplishing a task,
Or
An algorithm is a finite sequence of well defined instructions that can be used to solve a
computational problem.
Or
It provides a step-by-step procedure that convert an input into a desired output.
Performance Analysis: Predicting how an algorithm will scale with larger inputs.
Optimization: Identifying bottlenecks (slowdown) and improving efficiency.
Resource Management: Ensuring algorithms run within acceptable time and space
limits. Algorithm complexity measures resource usage.
The time complexity of an algorithm is the amount of time required to complete the
execution.
The time complexity of an algorithm is denoted by the big O notation.
Number of primitive operations executed.
Example 1: Constant Time (Time does not change, even if input increases.)
int x = a + b;
Time Complexity: O (1)
Dell | [SCHOOL]
Example 2: Linear Time (Time increases proportionally with input)
for(int i = 0; i < n; i++)
printf("%d", i);
Time Complexity: O(n)
2. Space Complexity
It depends on:
Program Space: the space required by the machine program generated by the compiler
or assembler.
Data Space: The space required to store the constants, variables etc,
Stack Space: The space required to store the return address along with parameters that
are passed to the function, local variables etc.
Dell | [SCHOOL]
Variable part includes:
Dynamic memory
Recursion stack
Data structures
Time-space trade-off
The time-space trade-off is a fundamental concept in computer science and algorithm design
that involves a balance between the time complexity (execution speed) and the space
complexity (memory usage) of an algorithm.
The general idea is that if you use memory, you might be able to speed up the algorithm, and
vice versa.
Key Points of time Space Trade-off:
1. More time for less Space: If you optimize for space (use less memory), it might take
more time to execute because it needs to recomputed results multiple times, or it
needs to traverse the input multiple times.
2. More Space for Less Time: If you optimize an algorithm for time (use more
memory),
It might run faster because you can store intermediate results (e.g., memorization,
caching and avoid redundant computations.
With memorization
Dell | [SCHOOL]
Trade-off: By using more space to store intermediate results, you reduce the time complexity
dramatically.
Dell | [SCHOOL]
Written as:
a mod b
Example:
10 mod 3 = 1
Because:
10 ÷ 3 → remainder = 1
Another example:
15 mod 4 = 3
Integer Function
Dell | [SCHOOL]
Example:
6. Permutations
nPr=n!/(n−r)!
Example:
5P2 = 5! / 3!
=5×4
= 20
Dell | [SCHOOL]
7. Exponents and Logarithms
Exponent
Power of number
Example:
2³ = 8
2⁴ = 16
Logarithm
Opposite of exponent
Example:
log₂(8) = 3
Because:
2³ = 8
Algorithmic Notations:
Algorithmic notations are methods used to define, design, and represent the step-by-step
procedures of an algorithm before they are implemented in a specific programming language.
The three primary notations are
1. Pseudocode
2. Flowcharts
3. Mathematical Notation.
1. Pseudocode
Pseudocode is a detailed, readable description of an algorithm that uses a mixture of natural
language (e.g., English) and high-level programming syntax, such as loops (for, while) and
conditionals (if-then-else).
Purpose: To plan program logic without worrying about strict syntax rules.
Characteristics:
o It is language-independent.
o It uses indentation to show hierarchy and control structures.
o Easier to convert to actual programming code compared to flowcharts.
Dell | [SCHOOL]
Example (Sum of Two Numbers):
START
DECLARE num1, num2, sum
READ num1, num2
sum = num1 + num2
PRINT sum
STOP
2. Flowcharts
A flowchart is a diagrammatic or graphical representation of an algorithm. It uses standard
symbols (rectangles, diamonds, ovals) connected by arrows to show the sequence of
operations.
Purpose: To visually represent the logic and flow of a system, making it easy to understand.
Standard Symbols:
o Oval (Terminator): Represents the Start/End.
o Parallelogram (Input/Output): Represents data input or output.
o Rectangle (Process): Represents calculations or actions.
o Diamond (Decision): Represents conditional branches.
Advantages: Excellent for visualizing complex logic.
Disadvantages: Can become complex and hard to modify for large, detailed programs.
3. Mathematical Notation
Mathematical notation uses symbols, formulas, and symbolic logic (such as set theory or
matrix notation) to define algorithmic steps, commonly used in numerical analysis, scientific
computing, and algorithm complexity analysis.
Dell | [SCHOOL]
[Precise: exact, specific, and accurate
Control structures
Sequence logic (Sequential flow): The default mode of execution where instructions are
performed one after another in the exact order they appear.
#include<stdio.h>
int main()
{
int a = 5, b = 3, sum;
sum = a + b;
printf("%d", sum);
return 0;
}
Selection logic (Conditional flow): Used for decision-making and branching. It allows the
program to choose between alternative paths based on whether a condition is true or false.
Examples include if, if-else, and switch statements.
#include<stdio.h>
int main()
{
int n = 10;
if(n > 0)
printf("Positive");
return 0;
Dell | [SCHOOL]
}
Iteration logic (Repetitive flow): Used to repeat a block of code multiple times as long as a
specific condition is met. Examples include for, while, and do-while loops.
#include<stdio.h>
int main()
{
int i;
return 0;
}
Complexity of algorithms
Why analysis of algorithm is important?
1. To predict the behaviour of an algorithm for large inputs (Scalable Software).
2. It is much more convenient to have simple measures for the efficiency of an algorithm
than to implement the algorithm and test the efficiency every time a certain parameter in
the underlying computer system changes.
3. More importantly, by analysing different algorithms, we can compare them to determine
the best one for our purpose.
If the problem is having more than one solution or algorithm then the best one is
decided by the analysis based on two factors.
1. CPU Time (Time complexity)
2. Main memory space (Space complexity)
Time complexity of an algorithm can be calculated by using two methods:
1. Posterior Analysis
2. Priori Analysis
Dell | [SCHOOL]
Posterior analysis is a relative analysis Prior analysis is an absolute analysis
The time complexity of an algorithm using a The time complexity of an algorithm using a
posteriori analysis differ from system to priori analysis is same for every system.
system.
If the time taken by the program is less, then If the algorithm running faster, credit goes
the credit will go to compiler and hardware. to the programmer.
Maintenance phase is required to tune the Maintenance phase is not required to tune
algorithm. the algorithm
Dell | [SCHOOL]
1. The space complexity of an algorithm is the total space taken by the algorithm with
respect to the input size.
2. Space complexity includes both Auxiliary space and space used by unit.
Order growth
The order of growth of an algorithm is an approximation of the time required to run a
computer program as the input size increases.
The order of growth ignores the constant factor needed for fixed operations and
focuses instead on the operations that increase proportional to input size.
Ex: a program with a linear order of growth generally requires double the time if the input
doubles.
Types of Order Growth of an Algorithm
Different types of Order of Growth of an Algorithm are shown below:
Order of Growth Description
1 Constant
log n Logarithmic
n Linear
n^2 Quadratic
n^3 Cubic
2n Exponential
Ex: If the algorithm input is 8, the number of steps executed by this algorithm is log 8(which
means three steps are performed to get the output).
Dell | [SCHOOL]
Linear Order of Growth (n)
The Linear Order of Growth means the number of steps executed by an algorithm is
same as the size of the input.
Ex: If the inputs are 10 or 100 or 1000, the algorithm executes those many numbers steps.
Ex: ten example, ten inputs mean the number of steps executed is 100.
O(n) Linear Search Time taken grows linearly with input size
O(n log n) Merge Sort Time taken grows linear ithmically with input
size.
Dell | [SCHOOL]
O(n^2) Bubble Sort Time taken grows quadratically with input size
In average case analysis, we consider all possible inputs and calculate the
running time for each input.
Then we add all the running times and divide by the total number of inputs to
get the average time.
In Linear Search, we assume that all cases are uniformly distributed, including
the case when the element is not present in the array.
So we sum all cases and divide by (n + 1), where n cases are for elements
present and 1 case is for element not present.
Dell | [SCHOOL]
Big-O notation represents the upper bound of the running time of an algorithm.
Omega notation (Ω) represents the lower bound of the running time of an algorithm.
f(n) = Ω(g(n))
Dell | [SCHOOL]
Big Theta notation (Θ-Notation)
Theta notation (Θ) represents both the upper bound and lower bound of the running
time of an algorithm.
f(n) = Θ(g(n))
Dell | [SCHOOL]
[Link].
Big O Big Omega (Ω) Theta (Θ)
Introduction to Strings
Strings are sequences of characters. The differences between a character array and a
string are, a string is terminated with a special character ‘\0’.
Storing String
How Strings are represented in Memory?
C: Strings are declared as character arrays or pointers and must end with a null
character (\0) to indicate termination.
Dell | [SCHOOL]
// C program to illustrate strings
#include <stdio.h>
int main()
{
// declare and initialize string
char str[] = "Geeks";
// print string
printf("%s", str);
return 0;
}
Character Data Types
A character data type (char) is used to store a single character, such as a letter, digit, or
symbol.
Characteristics
It stores only one character at a time.
It is written inside single quotes (' ').
It occupies 1 byte of memory.
The value is stored as an ASCII code internally.
Dell | [SCHOOL]
Description Character Literal Example
Alphabet character 'A', 'b', 'Z'
Digit character '0', '5', '9'
Special symbol '@', '#', '%'
Space character ' '
Escape character '\n', '\t', '\0'
String Operations
1. Insertion Operation: Adding a new character or string at a specific position in a
string.
Example: strcat(str, "World"); // Inserts "World" at the end of str
Characteristics of String:
A string stores multiple characters.
It is written inside double quotes (" ").
It is stored in a character array.
The string always ends with a null character \0.
Dell | [SCHOOL]
Special character string "@#$%", "!&*"
(symbols)
Mixed string (letters, "C@2025!", "A1#B2"
numbers, symbols)
Hexadecimal string "\x41", "\x42"
String containing backslash "C:\\Program Files"
String containing double "He said \"Hello\""
quote
Word processing
A word processor is a tool used to create, edit, format, and print text documents.
It processes text into pages and paragraphs.
Word processors are of three types:
1. Mechanical word processors
2. Electronic word processors
3. Software word processors
Word processing software helps in editing, formatting, designing, and managing text
in documents.
Today, word processors are mainly software programs that run on general-purpose
computers.
Wordpad
Microsoft Word
Lotus word pro
Notepad
WordPerfect (Windows only),
AppleWorks (Mac only),
Dell | [SCHOOL]
Work pages
OpenOffice Writer
Features
Functions
Dell | [SCHOOL]
Advantages
Disadvantages
It does not give you complete control over the look and feel of your document.
It did not develop out of computer technology.
Dell | [SCHOOL]
Features of Pattern Searching Algorithm
Pattern searching algorithms should recognize familiar patterns quickly and accurately.
Recognize and classify unfamiliar patterns.
Identify patterns even when partly hidden.
Recognize patterns quickly with ease, and with automaticity.
#include <stdio.h>
#include <string.h>
int main() {
char text[] = "AABAACAADAABAABA";
char pattern[] = "AABA";
int n = strlen(text);
int m = strlen(pattern);
Dell | [SCHOOL]
int i, j;
for(i = 0; i <= n - m; i++) {
for(j = 0; j < m; j++) {
if(text[i + j] != pattern[j])
break;
}
if(j == m)
printf("Pattern found at index %d\n", i);
}
return 0;
}
Example
Text: AABAACAADAABAABA
Pattern: AABA
Output:
Pattern found at index 0
Pattern found at index 9
Pattern found at index 12
Recursion:
Definition: The process in which a function calls itself directly or indirectly is called
recursion and the corresponding function is called a recursive function.
Types
Type of Definition Example
Recursion
Indirect A function calls another function which again A() → B() → A()
Recursion calls the first function.
Tail Recursion The recursive call is the last statement in the return fact(n-
1);
function.
Head Recursion The recursive call occurs before other operations fun(n-1);
Dell | [SCHOOL]
in the function. printf("%d", n);
Recursion
Examples: (Factorial)
#include <stdio.h>
int fact(int n) {
// Base Condition
if (n == 0)
return 1;
return n * fact(n - 1);
}
int main() {
printf("Factorial of 5 : %d\n", fact(5));
return 0;
}
Factorial of 5 : 120
Dell | [SCHOOL]
UNIT II
Arrays: Definition
Arrays are defined as the collection of similar types of data items stored at contiguous memory
location.
Properties of array:
Each array element has the same data type and size (4 bytes).
Elements are stored in contiguous memory, starting at the smallest address.
Elements can be randomly accessed using the base address and element size
Linear arrays
A linear array is a collection of elements of the same data type stored in consecutive
memory locations and accessed using a single index.
Elements are stored one after another in memory.
Accessed using one index (arr[i]).
All elements are of the same data type.
Supports random access.
Arrays as ADT
An abstract data type (ADT) is a data structure that defines a set of operations.
Arrays can be considered as an ADT because they provide a set of operations that
allow us to manipulate the data contained within them.
Characteristics of array as ADTs
Fixed Size: The size of the array is defined at creation and cannot be changed.
Homogeneous Data: All elements in the array are of the same data type.
Indexed Access: Elements are accessed using an index (position).
Efficient Memory Allocation: Elements are stored in contiguous memory locations,
enabling fast access.
Dell | [SCHOOL]
Delete: Remove an element from a specific index.
Access: Get an element using its index.
Update: Modify the element at a specific index.
Size/Length: Get the total number of elements.
Search: Find the position of a specific element.
Traversal: Iterate through all array elements.
Example:
#include <stdio.h>
struct Array {
int data[MAX];
int size;
};
// Insert at end
arr->data[arr->size] = value;
arr->size++;
// Access element
return [Link][index];
// Update element
arr->data[index] = value;
Dell | [SCHOOL]
}
// Delete element
arr->size--;
// Traverse array
printf("\n");
int main() {
[Link] = 0;
insert(&arr, 10);
insert(&arr, 20);
insert(&arr, 30);
traverse(arr);
update(&arr, 1, 25);
traverse(arr);
delete(&arr, 0);
Dell | [SCHOOL]
traverse(arr);
return 0;
Output:
10 20 30
10 25 30
25 30
Element at index 1: 30
Declaration is static or compile-time memory allocation, which means that the array
element's memory is allocated when a program is compiled.
Dell | [SCHOOL]
Example:
int A[5] = {10, 20, 30, 40, 50};
If each integer takes 4 bytes, then the array is stored in memory as:
A[0] 10 1000
A[1] 20 1004
A[2] 30 1008
A[3] 40 1012
A[4] 50 1016
Basic Operations:
Traversal: Visiting or accessing each element of the array one by one.
Insertion: Adding a new element at a specific position in the array.
Deletion: Removing an element from a specific position in the array.
Search: Finding the location of a particular element in the array.
Update: Modifying or changing the value of an existing element in the array.
Traversal
Dell | [SCHOOL]
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
for(int i=0; i<3; i++)
printf("%d ", arr[i]);
}
Output:
10 20 30
#include <stdio.h>
int main( ) {
int arr[5] = {10, 20, 30, 40};
int n = 4, pos = 2, value = 25;
for(int i=n; i>pos; i--)
arr[i] = arr[i-1];
arr[pos] = value;
n++;
for(int i=0; i<n; i++)
printf("%d ", arr[i]);
}
Output:
10 20 25 30 40
#include <stdio.h>
int main() {
Dell | [SCHOOL]
arr[i] = arr[i+1];
n--;
Output: 20 30 40
#include <stdio.h>
int main() {
int arr[4] = {10, 20, 30, 40};
int key = 30;
for(int i=0; i<4; i++){
if(arr[i] == key){
printf("Element found at index %d", i);
break;
}
}
}
Output:
Element found at index 2
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
arr[1] = 50;
for(int i=0; i<3; i++)
printf("%d ", arr[i]);
}
Output:
Dell | [SCHOOL]
10 50 30
Dell | [SCHOOL]
printf("%d", arr[1]);
}
Output
20
Dynamic Size Array:
An array whose size can be allocated or changed during runtime using dynamic memory
allocation.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
arr = (int*) malloc(3 * sizeof(int));
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
printf("%d", arr[2]);
}
Output
30
One-Dimensional Array:
An array that stores elements in a single row and is accessed using one index.
#include <stdio.h>
int main() {
int arr[4] = {5, 10, 15, 20};
printf("%d", arr[3]);
}
Output
20
Multi-dimensional arrays
A multi-dimensional array is an array with more than one dimension.
Two-Dimensional Arrays
A 2D array is also known as a matrix (a table of rows and columns).
Dell | [SCHOOL]
To create a 2D array of integers,
Example:
int matrix [2][3] = { {1, 4, 2}, {3, 6, 8} };
The first dimension represents the number of rows [2], while the second dimension represents
the number of columns [3].
Example:
#include <stdio.h>
int main() {
Dell | [SCHOOL]
int arr[2][3], i, j;
printf("Enter 6 numbers:\n");
// Input
scanf("%d", &arr[i][j]);
// Output
printf("\n");
return 0;
Example Input
Enter 6 numbers:
1 2 3
4 5 6
Output
The 2D array is:
1 2 3
4 5 6
Matrices
A Matrix is a rectangular arrangement of elements (numbers/data) in the form of rows
and columns.
Types of Matrices
Row Matrix: Matrix having only one row.
Column Matrix: Matrix having only one column.
Dell | [SCHOOL]
Square Matrix: Matrix having same number of rows and columns.
Diagonal Matrix: All elements except diagonal are 0.
Identity Matrix: Diagonal elements are 1, others are 0.
Zero (Null) Matrix: All elements are 0.
Sparse matrices
A matrix is a two-dimensional data object made of m rows and n columns, therefore having
total m x n values. If most of the elements of the matrix have 0 value, then it is called a
sparse matrix.
Why to use Sparse Matrix instead of simple matrix?
Storage: There are lesser non-zero elements than zeros and thus lesser memory can be
used to store only those elements.
Computing time: Computing time can be saved by logically designing a data structure
traversing only non-zero elements.
00304
00570
00000
02600
1. Array representation
2D array is used to represent a sparse matrix in which there are three rows named as
Dell | [SCHOOL]
// C program for Sparse Matrix Representation
#include<stdio.h>
int main()
{
// Assume 4x5 sparse matrix
int sparseMatrix[4][5] =
{
{0 , 0 , 3 , 0 , 4 },
{0 , 0 , 5 , 7 , 0 },
{0 , 0 , 0 , 0 , 0 },
{0 , 2 , 6 , 0 , 0 }
};
int size = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 5; j++)
if (sparseMatrix[i][j] != 0)
size++;
// number of columns in compactMatrix (size) must be
// equal to number of non - zero elements in
// sparseMatrix
int compactMatrix[3][size];
// Making of new matrix
int k = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 5; j++)
Dell | [SCHOOL]
if (sparseMatrix[i][j] != 0)
{
compactMatrix[0][k] = i;
compactMatrix[1][k] = j;
compactMatrix[2][k] = sparseMatrix[i][j];
k++;
}
for (int i=0; i<3; i++)
{
for (int j=0; j<size; j++)
printf("%d ", compactMatrix[i][j]);
printf("\n");
}
return 0;
}
Output
001133
242312
345726
Searching
Linear Search
Linear search is a searching technique in which each element of a list or array is checked
one by one sequentially until the required element is found or the list ends.
Array:
A = [10, 25, 30, 45, 50]
Element to search: 30
Steps
Dell | [SCHOOL]
Steps:
#include <stdio.h>
int main() {
int a[5] = {10, 25, 30, 45, 50};
int i, key = 30;
for(i = 0; i < 5; i++) {
if(a[i] == key) {
printf("Element found at position %d", i + 1);
return 0;
}
}
printf("Element not found");
return 0;
}
Output:
Element found at position 3
Advantages
Simple and easy to implement
Works on unsorted data
Suitable for small datasets
No extra memory required
Disadvantages
Slow for large datasets
Requires checking each element one by one
Time complexity is O(n) (worst case)
Binary Search
Dell | [SCHOOL]
Array (sorted): A = [10, 20, 30, 40, 50]
Element to search: 40
Steps
Algorithm
Example:
#include <stdio.h>
int main() {
int a[5] = {10, 20, 30, 40, 50};
int low = 0, high = 4, mid, key = 40;
while(low <= high) {
mid = (low + high) / 2;
if(a[mid] == key) {
printf("Element found at position %d", mid + 1);
return 0;
}
else if(a[mid] < key)
low = mid + 1;
else
Dell | [SCHOOL]
high = mid - 1;
}
printf("Element not found");
return 0;
}
Output:
Element found at position 4
Advantages
Faster than linear search
Time complexity is O(log n)
Efficient for large datasets
Disadvantages
Sorting
1. Bubble sort
Bubble sort repeatedly compares adjacent elements and swaps them if they are in the
wrong order.
#include <stdio.h>
int main() {
int a[5] = {5, 1, 4, 2, 8};
int i, j, temp;
for(i = 0; i < 5; i++) {
for(j = 0; j < 5-i-1; j++) {
if(a[j] > a[j+1]) {
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Dell | [SCHOOL]
printf("Sorted array: ");
for(i = 0; i < 5; i++)
printf("%d ", a[i]);
return 0;
}
Output: Sorted array: 1 2 4 5 8
2. Selection sort
Selection sort repeatedly selects the smallest element from the unsorted part and places it
at the beginning.
#include <stdio.h>
int main() {
int a[5] = {64, 25, 12, 22, 11};
int i, j, min, temp;
Dell | [SCHOOL]
3. Insertion sort
Insertion sort places each element in its correct position in the sorted part of the array.
#include <stdio.h>
int main() {
int a[5] = {12, 11, 13, 5, 6};
int i, j, key;
for(i = 1; i < 5; i++) {
key = a[i];
j = i - 1;
while(j >= 0 && a[j] > key) {
a[j+1] = a[j];
j = j - 1;
}
a[j+1] = key;
}
printf("Sorted array: ");
for(i = 0; i < 5; i++)
printf("%d ", a[i]);
return 0;
}
Output: Sorted array: 5 6 11 12 13
Dell | [SCHOOL]
4. Merge sort
Merge sort divides the array into smaller parts, sorts them, and then merges them together.
#include <stdio.h>
void merge(int a[], int low, int mid, int high) {
int i = low, j = mid + 1, k = low;
int temp[50];
while(i <= mid && j <= high) {
if(a[i] <= a[j]) {
temp[k] = a[i];
i++;
}
else {
temp[k] = a[j];
j++;
}
k++;
}
while(i <= mid) {
temp[k] = a[i];
i++;
k++;
}
while(j <= high) {
temp[k] = a[j];
j++;
k++;
}
for(i = low; i <= high; i++)
a[i] = temp[i];
}
void mergesort(int a[], int low, int high) {
if(low < high) {
int mid = (low + high) / 2;
Dell | [SCHOOL]
mergesort(a, low, mid);
mergesort(a, mid + 1, high);
merge(a, low, mid, high);
}
}
int main() {
int a[5] = {8, 3, 5, 2, 7};
int i;
mergesort(a, 0, 4);
printf("Sorted array: ");
for(i = 0; i < 5; i++)
printf("%d ", a[i]);
return 0;
}
Quick sort
#include <stdio.h>
void quicksort(int a[], int low, int high) {
int i = low, j = high, pivot, temp;
pivot = a[(low + high) / 2];
while(i <= j) {
while(a[i] < pivot)
i++;
while(a[j] > pivot)
j--;
if(i <= j) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
if(low < j)
quicksort(a, low, j);
Dell | [SCHOOL]
if(i < high)
quicksort(a, i, high);
}
int main() {
int a[5] = {8, 3, 5, 2, 7};
int i;
quicksort(a, 0, 4);
printf("Sorted array: ");
for(i = 0; i < 5; i++)
printf("%d ", a[i]);
return 0;
}
Dell | [SCHOOL]