0% found this document useful (0 votes)
10 views

dsa_notes

The document provides an overview of searching and sorting algorithms, detailing Linear Search and Binary Search for searching, and Bubble Sort, Selection Sort, Insertion Sort, and Merge Sort for sorting. Each algorithm is explained with its working process, time complexities, and example code in C. The document emphasizes the importance of these algorithms in efficiently retrieving and organizing data.

Uploaded by

garry1002003
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 views

dsa_notes

The document provides an overview of searching and sorting algorithms, detailing Linear Search and Binary Search for searching, and Bubble Sort, Selection Sort, Insertion Sort, and Merge Sort for sorting. Each algorithm is explained with its working process, time complexities, and example code in C. The document emphasizes the importance of these algorithms in efficiently retrieving and organizing data.

Uploaded by

garry1002003
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/ 23

Searching Algorithm:

Searching algorithm is the process of finding the existence of a specific element, within
an array, list, or tree. It is a fundamental operation which is used to retrieve data efficiently.
Types of Searching Algorithms
1. Linear Search 2. Binary Search

1. Linear Search : Linear Search is a basic searching algorithm that checks each element
of the data structure sequentially until the desired element is found.
Working of Linear Search :
i) Start from the first element.
ii) Compare each element with the key.
iii) If a match is found, return its position.
iv) If no match is found after checking all elements, return "Not Found".
Time Complexity :
• Best Case: O(1) → if key is the first element
• Worst Case: O(n) → if key is the last element or not present
• Space Complexity: O(1)

Prog.
#include <stdio.h>
void linearSearch(int arr[], int n, int key) {
int i;

for (i = 0; i < n; i++) {


if (arr[i] == key) {
printf("Element found at index %d (position %d).\n", i, i + 1);
return;
}
}
// If element is not found
printf("Element not found in the array.\n");
}

void main() {
int n, key, i;

// Input the number of elements


printf("Enter the number of elements in the array: ");
scanf("%d", &n);

int arr[n];

// Input elements of the array


printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Input the element to search


printf("Enter the element to search: ");
scanf("%d", &key);

// Call the linear search function


linearSearch(arr, n, key);
}
2. Binary Search : Binary Search is an efficient searching algorithm that finds the
position of a target value in a sorted array by repeatedly dividing the search interval
in half.
Note : It works only on arrays that are sorted in ascending or descending order.

Working of Binary Search :


 Start with a sorted array.
Binary search only works on data that is already in ascending or descending order.
 Initialize two variables:
 low = 0 (start index)
 high = n - 1 (end index)
 Repeat while low <= high:
a. Calculate the middle index:
mid = (low + high) / 2
b. Compare the middle element arr[mid] with the key:
 If arr[mid] == key:
→ Element is found at index mid
 If arr[mid] < key:
→ Search in the right half by setting low = mid + 1
 If arr[mid] > key:
→ Search in the left half by setting high = mid - 1
 If the loop ends without finding the element:
→ The element is not present in the array.
Example:
Array: 10, 20, 30, 40, 50
Search Key: 30
• Step 1: low = 0, high = 4, mid = 2
• Step 2: arr[2] = 30 → Element found!

Time Complexity of Binary Search :


Binary Search reduces the search space by half with each step. So, for an array of n elements,
it will take at most log₂(n) steps.

Time Complexities

Case Time Complexity Explanation

Best O(1) If the element is found at the first middle check

Average O(log n) Each comparison cuts the array in half

Worst O(log n) Element is at the end or not present at all


Prog.
#include <stdio.h>
void binarySearch(int arr[], int n, int key) {
int low = 0;
int high = n - 1;
int mid;

while (low <= high) {


mid = (low + high) / 2;

if (arr[mid] == key) {
printf("Element found at index %d (position %d).\n", mid, mid + 1);
return;
} else if (arr[mid] < key) {
low = mid + 1;
} else {
high = mid - 1;
}
}

// If not found
printf("Element not found in the array.\n");
}

void main() {
int n, key;

// Input array size


printf("Enter the number of elements in the array: ");
scanf("%d", &n);
int arr[n];

// Input sorted array elements


printf("Enter %d sorted elements (ascending order):\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Input key to search


printf("Enter the element to search: ");
scanf("%d", &key);

// Call binary search


binarySearch(arr, n, key);
}

Sorting Algorithms:

Sorting algorithms are methods used to arrange the elements of a list or array in a specific
order — typically ascending or descending.
Sorting helps in organizing data and makes searching and other operations more efficient.

Types of Sorting Algorithms :


Sorting algorithms can be classified based on technique, complexity, and stability. Here's a
basic list of common types:
1. Bubble Sort 2. Selection Sort 3. Insertion Sort
4. Merge Sort 5. Quick Sort 6. Heap Sort

1. Bubble Sort : Bubble Sort is a simple sorting algorithm that works by repeatedly
swapping adjacent elements if they are in the wrong order.
It continues doing this until the entire array is sorted.
Working Process of Bubble Sort :

 Start from the beginning of the array.


 Compare the first and second elements:
o If the first is greater than the second, swap them.
 Move to the next pair, compare and swap if needed.
 Repeat this process for all elements.
 After each full pass, the largest unsorted element "bubbles up" to its correct
position.
 Repeat the passes until the array is sorted.

Example
Array: 5 3 8 4 2
• Pass 1: 3 5 4 2 8
• Pass 2: 3 4 2 5 8
• Pass 3: 3 2 4 5 8

• Pass 4: 2 3 4 5 8 =➔Sorted!

Time Complexity

Case Time Complexity

Best O(n) (if already sorted)

Average O(n²)

Worst O(n²)

Prog.
#include <stdio.h>
void bubbleSort(int arr[], int n) {
int i, j, temp;

for (i = 0; i < n - 1; i++) {


// Flag to check if any swapping happened
int swapped = 0;

for (j = 0; j < n - i - 1; j++) {


// Compare adjacent elements
if (arr[j] > arr[j + 1]) {
// Swap if elements are in wrong order
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;

swapped = 1;
}
}

// If no two elements were swapped, the array is already sorted


if (swapped == 0) {
break;
}
}
}

void main() {
int n, i;

// Input number of elements


printf("Enter the number of elements: ");
scanf("%d", &n);

int arr[n];

// Input array elements


printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Call the bubble sort function


bubbleSort(arr, n);

// Print sorted array


printf("Sorted array in ascending order:\n");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}

2. Selection Sort : Selection Sort is a simple sorting algorithm that works by repeatedly
finding the smallest (or largest) element from the unsorted part of the array and swapping it
with the first unsorted element.
It divides the array into two parts:
• Sorted part (built from the front)
• Unsorted part (remaining elements)
Working Process of Selection Sort :

 Start with the first element.


 Find the smallest element in the unsorted part of the array.
 Swap it with the first unsorted element.
 Move to the next position and repeat the process until the array is fully sorted

Example
Array: 29, 10, 14, 37, 14
• Pass 1: Find minimum → 10 → Swap with 29 → 10, 29, 14, 37, 14
• Pass 2: Min is 14 → Swap with 29 → 10, 14, 29, 37, 14
• Pass 3: Min is 14 → Swap with 29 → 10, 14, 14, 37, 29
• Pass 4: Min is 29 → Swap with 37 → 10, 14, 14, 29, 37 ➔ Sorted

Time Complexity :
Case Time Complexity

Best O(n²)

Average O(n²)

Worst O(n²)

Prog.

#include <stdio.h>
void selectionSort(int arr[], int n) {
int i, j, minIndex, temp;

for (i = 0; i < n - 1; i++) {


minIndex = i;

// Find the index of the smallest element in the unsorted part


for (j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}

// Swap the found minimum element with the first unsorted element
if (minIndex != i) {
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
void main() {
int n, i;

// Input array size


printf("Enter the number of elements: ");
scanf("%d", &n);

int arr[n];

// Input array elements


printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Sort the array using Selection Sort


selectionSort(arr, n);

// Print sorted array


printf("Sorted array in ascending order:\n");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}

3. Insertion Sort : Insertion Sort is a sorting algorithm in which elements are picked
one by one and inserted into their correct position in the already sorted part of the
array.
It maintains a sorted subarray on the left side and gradually inserts each new element
into its correct place.
Working Process of Insertion Sort :

 Assume the first element is already sorted.


 Take the next element and compare it with the elements in the sorted part.
 Shift elements to the right until the correct position is found.
 Insert the current element into that position.
 Repeat for all remaining elements.

Example
Array: 5, 3, 4, 1
• Pass 1: 3 inserted before 5 → 3, 5, 4, 1
• Pass 2: 4 inserted between 3 and 5 → 3, 4, 5, 1
• Pass 3: 1 inserted at the beginning → 1, 3, 4, 5 ➔ Sorted

Time Complexity

Case Time Complexity

O(n) (already
Best
sorted)

Average O(n²)

Worst O(n²)

#include <stdio.h>
void insertionSort(int arr[], int n) {
int i, j, key;

for (i = 1; i < n; i++) {


key = arr[i];
j = i - 1;

// Move elements that are greater than key


// to one position ahead of their current position
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
// Insert the key into its correct position
arr[j + 1] = key;
}
}

void main() {
int n, i;

// Input number of elements


printf("Enter the number of elements: ");
scanf("%d", &n);

int arr[n];

// Input elements
printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Sort the array using Insertion Sort


insertionSort(arr, n);

// Print sorted array


printf("Sorted array in ascending order:\n");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}
4. Merge Sort : Merge Sort is a divide and conquer sorting algorithm that divides the
array into two halves, sorts them recursively, and then merges the sorted halves to get
the final sorted array.

Working Process of Merge Sort :

 Divide the array into two halves.


 Recursively sort both halves.
 Merge the two sorted halves into one sorted array.

Example
Array: 6, 3, 8, 2
1. Divide: [6, 3] and [8, 2]
2. Divide again: [6] [3] [8] [2]
3. Merge: [3, 6] and [2, 8]
4. Final merge: [2, 3, 6, 8] ➔ Sorted

Time Complexity :

Time
Case
Complexity

Best O(n log n)

Average O(n log n)

Worst O(n log n)

Prog.
#include <stdio.h>

// Merge two halves of the array


void merge(int arr[], int left, int mid, int right) {
int i, j, k;
int n1 = mid - left + 1; // Size of left half
int n2 = right - mid; // Size of right half
// Temporary arrays
int L[n1], R[n2];

// Copy data to temp arrays


for (i = 0; i < n1; i++)
L[i] = arr[left + i];

for (j = 0; j < n2; j++)


R[j] = arr[mid + 1 + j];

// Merge the temp arrays back into arr[]


i = 0;
j = 0;
k = left;

while (i < n1 && j < n2) {


if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}

// Copy remaining elements of L[]


while (i < n1) {
arr[k] = L[i];
i++;
k++;
}

// Copy remaining elements of R[]


while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}

// Recursive merge sort function


void mergeSort(int arr[], int left, int right) {
if (left < right) {
int mid = (left + right) / 2;

// Sort first and second halves


mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);

// Merge the sorted halves


merge(arr, left, mid, right);
}
}

void main() {
int n, i;

printf("Enter the number of elements: ");


scanf("%d", &n);

int arr[n];

printf("Enter %d elements:\n", n);


for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Call merge sort


mergeSort(arr, 0, n - 1);

// Print sorted array


printf("Sorted array in ascending order:\n");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}

5. Quick Sort : Quick Sort is a fast and efficient divide and conquer sorting algorithm
that works by selecting a pivot element, partitioning the array around the pivot, and
then recursively sorting the left and right subarrays.
Working Process of Quick Sort :
 Choose a pivot element from the array (commonly first, last, or middle element).
 Partition the array:
 Place elements smaller than pivot on the left,
 Place elements greater than pivot on the right.
 Recursively apply Quick Sort on the left and right parts.
 The array becomes sorted after all partitions are complete.

Example
Array: 5, 3, 8, 4, 2
• Choose pivot = 2
→ Partition: [2] | [3, 8, 4, 5]
• Choose pivot = 3
→ Partition: [2, 3] | [4, 8, 5]
• Continue recursively
→ Final sorted: [2, 3, 4, 5, 8]

Time Complexity

Case Time Complexity

Best O(n log n)

Average O(n log n)

Worst O(n²) → happens when array is already sorted and poor pivot is chosen

#include <stdio.h>

// Function to swap two elements


void swap(int arr[], int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

// Partition function using last element as pivot


int partition(int arr[], int low, int high) {
int pivot = arr[high]; // Pivot is the last element
int i = low - 1;

for (int j = low; j < high; j++) {


if (arr[j] < pivot) {
i++;
swap(arr, i, j);
}
}

swap(arr, i + 1, high); // Place pivot in correct position


return i + 1;
}

// Quick Sort function


void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);

quickSort(arr, low, pi - 1); // Sort left part


quickSort(arr, pi + 1, high); // Sort right part
}
}

void main() {
int n;

printf("Enter the number of elements: ");


scanf("%d", &n);

int arr[n];

printf("Enter %d elements:\n", n);


for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Call Quick Sort


quickSort(arr, 0, n - 1);

// Print sorted array


printf("Sorted array in ascending order:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}
6. Heap Sort : Heap Sort is a comparison-based sorting algorithm that uses a binary heap
data structure (usually a max heap) to sort elements.
It builds a heap from the input data, then repeatedly removes the maximum element from the
heap and places it at the end of the array.

Q. What is a Heap?
Ans : A heap is a special binary tree:
o Max Heap: Each parent node is greater than or equal to its children.
o Min Heap: Each parent node is less than or equal to its children.
• In Heap Sort, we use a Max Heap to get the largest element at the root.
Working Process of Heap Sort :

 Build a Max Heap from the array.


 The largest element is now at the root (index 0).
 Swap it with the last element of the array.
 Reduce the heap size by 1 (ignore the last sorted element).
 Heapify the root again to maintain the heap property.
 Repeat steps 3–5 until the entire array is sorted.

Example (Array):
Input: 4, 10, 3, 5, 1
1. Build Max Heap → 10, 5, 3, 4, 1
2. Swap 10 with 1 → 1, 5, 3, 4, 10
3. Heapify again → 5, 4, 3, 1, 10
4. Repeat...
Final sorted array: 1, 3, 4, 5, 10

Time Complexity

Time
Case
Complexity

Best O(n log n)

Average O(n log n)

Worst O(n log n)

Prog .

#include <stdio.h>

// Function to heapify a subtree rooted at index i


void heapify(int arr[], int n, int i) {
int largest = i; // Initialize largest as root
int left = 2 * i + 1; // left child
int right = 2 * i + 2; // right child

// If left child is larger than root


if (left < n && arr[left] > arr[largest]) {
largest = left;
}

// If right child is larger than largest so far


if (right < n && arr[right] > arr[largest]) {
largest = right;
}

// If largest is not root


if (largest != i) {
// Swap arr[i] and arr[largest]
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;

// Recursively heapify the affected sub-tree


heapify(arr, n, largest);
}
}

// Main function to do heap sort


void heapSort(int arr[], int n) {
// Build a max heap
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}

// One by one extract elements from heap


for (int i = n - 1; i >= 0; i--) {
// Move current root to end
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;

// call max heapify on the reduced heap


heapify(arr, i, 0);
}
}

void main() {
int n;

printf("Enter number of elements: ");


scanf("%d", &n);

int arr[n];

printf("Enter %d elements:\n", n);


for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Perform heap sort


heapSort(arr, n);

// Print sorted array


printf("Sorted array in ascending order:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
}

You might also like