diff --git a/sorting/heap_sort/heap_sort.java b/sorting/heap_sort/heap_sort.java new file mode 100644 index 0000000..2e0e796 --- /dev/null +++ b/sorting/heap_sort/heap_sort.java @@ -0,0 +1,62 @@ +package Data_Structures_and_Algorithms.sorting.heap_sort; + +import java.util.Arrays; + +public class heap_sort { + + public static void maxheapify(int[] A, int start, int end ){ + int left = 2 * start + 1; + int right = 2 * start + 2; + int largest = start; + + if(left < end && A[left] > A[largest]) { + largest = left; + } + + if(right < end && A[right] > A[largest]){ + largest = right; + } + + if(largest != start){ + int temp = A[largest]; + A[largest] = A[start]; + A[start] = temp; + + maxheapify(A, largest , end); + } + } + + public static void buildMaxHeap(int[] A, int start , int end){ + + for(int i= (end - 1) / 2; i >= start; i--){ + maxheapify(A, i, end); + } + } + + public static void heapSort(int[] A, int start, int end){ + + if (A == null || start < 0 || end > A.length || start >= end) { + throw new IllegalArgumentException("Invalid start or end indices."); + } + + if( end - start <=1){ + return; + } + + buildMaxHeap(A, start, end); + + for(int i = end - 1; i > start; i--){ + int temp = A[start]; + A[start] = A[i]; + A[i] = temp; + maxheapify(A, start, i); + } + } + + public static void main(String[] args){ + int[] A={8, 1, 2, 9, 4, 4 , 3, 3, 3 ,3}; + System.out.println("Unsorted array: " + Arrays.toString(A)); + heapSort(A, 0 , A.length); + System.out.println("Sorted array using Heap Sort: " + Arrays.toString(A)); + } +} diff --git a/sorting/insertion_sort/insertion_sort.java b/sorting/insertion_sort/insertion_sort.java new file mode 100644 index 0000000..bfb9b42 --- /dev/null +++ b/sorting/insertion_sort/insertion_sort.java @@ -0,0 +1,31 @@ +package Data_Structures_and_Algorithms.sorting.insertion_sort; + +import java.util.Arrays; + +public class insertion_sort { + + public static void insertionSort(int[] A, int start, int end){ + + if( end - start <=1){ + return; + } + + for( int i = start + 1; i < end; i++){ + int j = i - 1; + int key = A[i]; + + while(j >= start && A[j] > key){ + A[j + 1] = A[j]; + j--; + } + A[j+1] = key; + } + } + + public static void main(String[] args){ + int[] A={9,8,7,6,5,4}; + System.out.println("Unsorted array: " + Arrays.toString(A)); + insertionSort(A, 0 , A.length); + System.out.println("Sorted array using Insertion Sort: " + Arrays.toString(A)); + } +} \ No newline at end of file diff --git a/sorting/intro_sort/intro_sort.java b/sorting/intro_sort/intro_sort.java new file mode 100644 index 0000000..60139f8 --- /dev/null +++ b/sorting/intro_sort/intro_sort.java @@ -0,0 +1,78 @@ +package Data_Structures_and_Algorithms.sorting.intro_sort; +import Data_Structures_and_Algorithms.sorting.heap_sort.heap_sort; +import Data_Structures_and_Algorithms.sorting.insertion_sort.insertion_sort; +import java.util.Arrays; + + +public class intro_sort { + + public static int partition(int[] A, int start, int end){ + end = end-1; + int pivot = A[end]; + int i = start - 1; + + for(int j = start; j < end; j++){ + if(A[j] < pivot){ + i++; + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + } + + int temp = A[i + 1]; + A[i + 1] = A[end]; + A[end] = temp; + + return i + 1; + } + + public static void introHelper(int[] A, int start , int end , int maxDepth){ + + // Helper function for Introsort that combines Quicksort, Heap Sort, and Insertion Sort. + + if(end - start < 16){ //Use Insertion Sort for small partitions + insertion_sort.insertionSort(A, start, end); + } + + else if (maxDepth == 0){ // Switch to Heap Sort if recursion depth limit reached + heap_sort.heapSort(A, start, end); + } + + else{ + int pivot = partition(A, start, end); // Quick Sort partitioning + introHelper(A, start, pivot, maxDepth-1); + introHelper(A, pivot + 1, end, maxDepth - 1); + } + } + + public static void introSort(int[] A){ + if(A.length <= 1){ // Array is already sorted if it has 0 or 1 element + return; + } + int maxDepth =(int) (2 * Math.log(A.length) / Math.log(2)); // Maximum allowed recursion depth + introHelper(A, 0, A.length, maxDepth); + } + + public static void main(String[] args) { + int[][] testCases = { + {}, // Empty array + {1}, // Single element + {5, 3}, // Two elements unsorted + {3, 5}, // Two elements sorted + {5, 3, 8, 6, 2}, // Multiple elements unsorted + {8, 6, 5, 3, 2}, // Multiple elements reverse sorted + {1, 1, 1}, // All elements identical + {-1, -5, -3}, // Negative numbers + {0}, // Single zero element + {10, 3, 4, 5, 1, 0, 4, 1} // normal test case + }; + + for (int[] testCase : testCases) { + System.out.println("Unsorted array: " + Arrays.toString(testCase)); + introSort(testCase); + System.out.println("Sorted array using Introsort: " + Arrays.toString(testCase)); + System.out.println(); + } + } +} diff --git a/sorting/intro_sort/intro_sort.py b/sorting/intro_sort/intro_sort.py new file mode 100644 index 0000000..2878a3e --- /dev/null +++ b/sorting/intro_sort/intro_sort.py @@ -0,0 +1,87 @@ +import math +from random import randint + +def insertionSort(A, start , end): + for j in range(start + 1, end + 1): + i = j - 1 + key = A[j] + + while i >= start and A[i] > key: + A[i+1] = A[i] + i -= 1 + + A[i+1] = key + + +def maxHeapify(A, start, end): + left = 2 * start + 1 + right = 2 * start + 2 + + if left < end and A[left] > A[start]: + largest = left + else: + largest = start + + if right < end and A[right] > A[largest]: + largest = right + + if largest != start: + A[start], A[largest] = A[largest], A[start] + maxHeapify(A, largest, end) + + +def buildMaxHeap(A, start, end): + for i in range(start + (end - start) // 2, start, -1): + maxHeapify(A, i, end) + + +def heapSort(A, start, end): + buildMaxHeap(A, start, end) + + for i in range(end-1, start, -1): + A[start], A[i] = A[i], A[start] + maxHeapify(A, start , i-1) + + +def partition(A, start, end): + pivot = A[end] + + i = start - 1 + + for j in range(start, end): + if A[j] < pivot: + i += 1 + A[i], A[j] = A[j], A[i] + + A[i+1], A[end] = A[end], A[i+1] + return i+1 + + +def introHelper(A, start, end, max_depth): + +# Helper function for Introsort that combines Quicksort, Heap Sort, and Insertion Sort. + + if end-start < 16: # Use Insertion Sort for small partitions + insertionSort(A, start, end) + + elif max_depth == 0: + heapSort(A, start, end) # Switch to Heap Sort if recursion depth limit reached + + else: + pivot = partition(A, start, end) # Quick Sort partitioning + introHelper(A, start, pivot - 1, max_depth-1) + introHelper(A, pivot + 1, end, max_depth -1) + + +def introSort(A): + if len(A) <= 1: # Array is already sorted if it has 0 or 1 element + return + max_depth = 2 * math.floor(math.log2(len(A))) # Maximum allowed recursion depth + introHelper(A, 0, len(A) - 1, max_depth) + + +if __name__ == "__main__": + A = [randint(0, 100) for _ in range(200)] + print("Unsorted array:", A) + introSort(A) + print("Sorted array using Heap Sort:", A)