diff --git a/sorting/introspective_sort/introspective_sort.py b/sorting/introspective_sort/introspective_sort.py new file mode 100644 index 0000000..3837ae7 --- /dev/null +++ b/sorting/introspective_sort/introspective_sort.py @@ -0,0 +1,92 @@ +from math import log2 +from random import randint + + +INSERTION_SORT_THRESHOLD = 16 + + +def insertionSort(A, left, right): + for i in range(left + 1, right + 1): + key = A[i] + j = i - 1 + + while j >= left and A[j] > key: + A[j + 1] = A[j] + j -= 1 + + A[j + 1] = key + + +def partition(A, left, right): + mid = left + (right - left) // 2 + pivot = A[mid] + A[mid], A[right] = A[right], A[mid] + + store_index = left + for i in range(left, right): + if A[i] < pivot: + A[store_index], A[i] = A[i], A[store_index] + store_index += 1 + + A[store_index], A[right] = A[right], A[store_index] + return store_index + + +def heapify(A, start, heap_size, root): + largest = root + left = 2 * root + 1 + right = 2 * root + 2 + + if left < heap_size and A[start + left] > A[start + largest]: + largest = left + + if right < heap_size and A[start + right] > A[start + largest]: + largest = right + + if largest != root: + A[start + root], A[start + largest] = A[start + largest], A[start + root] + heapify(A, start, heap_size, largest) + + +def heapSort(A, left, right): + heap_size = right - left + 1 + + for i in range(heap_size // 2 - 1, -1, -1): + heapify(A, left, heap_size, i) + + for i in range(heap_size - 1, 0, -1): + A[left], A[left + i] = A[left + i], A[left] + heapify(A, left, i, 0) + + +def introSortUtil(A, left, right, max_depth): + size = right - left + 1 + + if size <= 1: + return + + if size <= INSERTION_SORT_THRESHOLD: + insertionSort(A, left, right) + return + + if max_depth == 0: + heapSort(A, left, right) + return + + pivot = partition(A, left, right) + introSortUtil(A, left, pivot - 1, max_depth - 1) + introSortUtil(A, pivot + 1, right, max_depth - 1) + + +def introSort(A): + if len(A) <= 1: + return + + max_depth = 2 * int(log2(len(A))) + introSortUtil(A, 0, len(A) - 1, max_depth) + + +A = [randint(0, 100) for _ in range(10)] +print(A) +introSort(A) +print(A) diff --git a/sorting/introspective_sort/java_implementation/IntrospectiveSort.java b/sorting/introspective_sort/java_implementation/IntrospectiveSort.java new file mode 100644 index 0000000..d1df0dc --- /dev/null +++ b/sorting/introspective_sort/java_implementation/IntrospectiveSort.java @@ -0,0 +1,113 @@ +import java.util.Arrays; + +public class IntrospectiveSort { + private static final int INSERTION_SORT_THRESHOLD = 16; + + public static void introSort(int[] arr) { + if (arr == null || arr.length <= 1) { + return; + } + + int maxDepth = 2 * (int) (Math.log(arr.length) / Math.log(2)); + introSortUtil(arr, 0, arr.length - 1, maxDepth); + } + + private static void introSortUtil(int[] arr, int left, int right, int maxDepth) { + int size = right - left + 1; + + if (size <= 1) { + return; + } + + if (size <= INSERTION_SORT_THRESHOLD) { + insertionSort(arr, left, right); + return; + } + + if (maxDepth == 0) { + heapSort(arr, left, right); + return; + } + + int pivot = partition(arr, left, right); + introSortUtil(arr, left, pivot - 1, maxDepth - 1); + introSortUtil(arr, pivot + 1, right, maxDepth - 1); + } + + private static void insertionSort(int[] arr, int left, int right) { + for (int i = left + 1; i <= right; i++) { + int key = arr[i]; + int j = i - 1; + + while (j >= left && arr[j] > key) { + arr[j + 1] = arr[j]; + j--; + } + + arr[j + 1] = key; + } + } + + private static int partition(int[] arr, int left, int right) { + int mid = left + (right - left) / 2; + int pivot = arr[mid]; + swap(arr, mid, right); + + int storeIndex = left; + for (int i = left; i < right; i++) { + if (arr[i] < pivot) { + swap(arr, storeIndex, i); + storeIndex++; + } + } + + swap(arr, storeIndex, right); + return storeIndex; + } + + private static void heapSort(int[] arr, int left, int right) { + int heapSize = right - left + 1; + + for (int i = heapSize / 2 - 1; i >= 0; i--) { + heapify(arr, left, heapSize, i); + } + + for (int i = heapSize - 1; i > 0; i--) { + swap(arr, left, left + i); + heapify(arr, left, i, 0); + } + } + + private static void heapify(int[] arr, int start, int heapSize, int root) { + int largest = root; + int left = 2 * root + 1; + int right = 2 * root + 2; + + if (left < heapSize && arr[start + left] > arr[start + largest]) { + largest = left; + } + + if (right < heapSize && arr[start + right] > arr[start + largest]) { + largest = right; + } + + if (largest != root) { + swap(arr, start + root, start + largest); + heapify(arr, start, heapSize, largest); + } + } + + private static void swap(int[] arr, int first, int second) { + int temp = arr[first]; + arr[first] = arr[second]; + arr[second] = temp; + } + + public static void main(String[] args) { + int[] arr = {29, 10, 14, 37, 13, 4, 9, 41, 2, 25}; + + System.out.println("Array before sorting: " + Arrays.toString(arr)); + introSort(arr); + System.out.println("Array after sorting: " + Arrays.toString(arr)); + } +}