diff --git a/README.md b/README.md index 18222d7..7b6bff0 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ This repository is one where we document the implementations and usage of differ - [Sort Algorithms](./src/com/sketch/sort/) - [Quick Sort](./src/com/sketch/sort/quicksort/QuickSort.md) - [Selection Sort](./src/com/sketch/sort/selectionsort/SelectionSort.md) + - [Insertion Sort](./src/com/sketch/sort/insertionsort/InsertionSort.md) ## Contributions This repository is open-source and available to everyone to wants to learn DSA or wants to contibute to documenting other algorithms. diff --git a/src/com/sketch/Main.java b/src/com/sketch/Main.java index 4486a78..7b8306b 100644 --- a/src/com/sketch/Main.java +++ b/src/com/sketch/Main.java @@ -1,24 +1,30 @@ package com.sketch; -import com.sketch.sort.quicksort.QuickSort; +import com.sketch.sort.insertionsort.InsertionSort; import java.util.Arrays; import java.util.Random; public class Main { public static void main(String[] args){ - int[] unsortedArray = new int[100]; + int[] unsortedArray = new int[10000]; Random random = new Random(); for(int i = 0; i < unsortedArray.length; i++){ - unsortedArray[i] = random.nextInt(20); + unsortedArray[i] = random.nextInt(50); } int[] unsortedArrayResult = new int[unsortedArray.length]; System.arraycopy(unsortedArray, 0, unsortedArrayResult, 0, unsortedArray.length); - QuickSort.sort(unsortedArrayResult, 0, unsortedArrayResult.length - 1); + long startTime = System.nanoTime(); - System.out.println("Actual Value Index: " + Arrays.toString(unsortedArray)); - System.out.println("Actual Value Index: " + Arrays.toString(unsortedArrayResult)); + InsertionSort.sort(unsortedArrayResult); + + long endTime = System.nanoTime(); + double duration = (endTime - startTime) / 1_000_000.0; + + System.out.println("Default Array: " + Arrays.toString(unsortedArray)); + System.out.println("Sorted Array: " + Arrays.toString(unsortedArrayResult)); + System.out.println("Execution Time: " + duration + "ms"); } } diff --git a/src/com/sketch/sort/insertionsort/InsertionSort.java b/src/com/sketch/sort/insertionsort/InsertionSort.java new file mode 100644 index 0000000..0604d94 --- /dev/null +++ b/src/com/sketch/sort/insertionsort/InsertionSort.java @@ -0,0 +1,15 @@ +package com.sketch.sort.insertionsort; + +public class InsertionSort { + public static void sort(int[] array){ + for(int i = 1; i < array.length; i++){ + int currentValue = array[i]; + int j = i - 1; + while (j >= 0 && array[j] > currentValue){ + array[j + 1] = array[j]; + j--; + } + array[j + 1] = currentValue; + } + } +} diff --git a/src/com/sketch/sort/insertionsort/InsertionSort.md b/src/com/sketch/sort/insertionsort/InsertionSort.md new file mode 100644 index 0000000..0a6c001 --- /dev/null +++ b/src/com/sketch/sort/insertionsort/InsertionSort.md @@ -0,0 +1,60 @@ +# Insertion Sort + +Insertion Sort is a simple, comparison-based algorithm that builds a sorted list one element at a time. +It works similarly to the way most people instinctively sort a hand of playing cards - by picking up one card at a time and inserting it into its correct position relative to the cards already held. + +The algorithm is classified as an in-place and stable sorting algorithm =, meaning it requires no additional memory proportional to the input size, +and it preserves the relative order of elements with equal keys. + +![img.png](img.png) + +Insertion Sort divides the input list into two conceptual parts: +- A sorted portion on the left, and +- An unsorted portion on the right. + +At the start, the sorted portion contains only the first element, since a single element is trivially sorted. +The algorithm then proceeds through the following steps for each remaining element: +- The current element is picked from the unsorted portion - *this is called the key*. +- The key is compared against the elements in the sorted portion, moving from right to left. +- Any sorted element that is greater than the key is shifted one position to the right to make room. +- Once the correct position is found, the key is inserted there. +- This process repeats until all elements have been moved from the unsorted portion into the sorted portion. + +By the time the algorithm reaches the last element, the entire list i guaranteed to be sorted. + +## Interesting facts +- Insertion Sort is one of the few sorting algorithms that can sort a list as it receives it - it is an online algorithm, meaning it does not need all elements to be present before it begins sorting. +- Unlike Bubble Sort and [Selection Sort](../selectionsort/SelectionSort.md), Insertion Sort performs very well on nearly sorted data, achieving close to linear time (O(n)) is such cases. +- The algorithm is naturally adaptive - its performance improves the more sorted the input already is. +- Insertion Sort is stable, meaning two elements with equal values will retain their original relative order after sorting. +- It is widely used in education settings as an introduction to sorting due to its intuitive, step-by-step nature. + +## Complexity Analysis +- Time Complexity + - Best Case: O(n) + - Average Case: O(n^2) + - Worst Case: O(n^2) +- Auxiliary Space: + - Best Case: O(1) + - Average Case: O(1) + - Worst Case: O(1) + +## Advantages +- Simple to understand and implement, making it ideal for learning and teaching sorting concepts. +- Very efficient on small datasets, often outperforming more complex algorithms like [Quick Sort](../quicksort/QuickSort.md) or Merge Sort at small sizes. +- Performs exceptionally well o nearly sorter or partially sorted data due to its adaptive nature. +- In-place sorting requires no extra memory allocation, making it memory efficient. +- Stable sort preserves the original order of equal elements, which is important in certain use cases such as sorting records with multiple fields. +- Online algorithm - can sort data as it arrives without needing the full dataset upfront. + +## Disadvantages +- Inefficient on large datasets due to its O(n^2) average and worst-case time complexity. +- Performance degrades significantly when the data is in reverse order, as every element must shift past all previously sorted elements. +- Not suitable as a general-purpose sorting algorithm for large-scale applications where performance is critical. +- Compared to divide-and-conquer algorithms like Merge Sort or [Quick Sort](../quicksort/QuickSort.md), ir does not scale well as input size grows. + +## Applications +- Used as a subroutine in Bucket Sort +- Can be useful when array is already almost sorted +- Since Insertion sort is suitable for small sized arrays, it is used in Hybrid Sorting algorithms along with other efficient algorithms like [Quick Sort](../quicksort/QuickSort.md) and Merge Sort. When the subarray size becomes small, we switch to insertion sort in these recursive algorithms. +- Embedded Systems: In low-memory environments such as micro-controllers, Insertion Sort's in-place O(1) space requirement makes it a practical choice. \ No newline at end of file diff --git a/src/com/sketch/sort/insertionsort/img.png b/src/com/sketch/sort/insertionsort/img.png new file mode 100644 index 0000000..1621b06 Binary files /dev/null and b/src/com/sketch/sort/insertionsort/img.png differ