diff --git a/C++/Sorting/Heapsort.cpp b/C++/Sorting/Heapsort.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0999eb98e98ba8ef5607223fa8816a37b4f37ac --- /dev/null +++ b/C++/Sorting/Heapsort.cpp @@ -0,0 +1,50 @@ +// Using std library to sort + +#include <algorithm> +#include <iterator> + +template<typename RandomAccessIterator> +void heap_sort(RandomAccessIterator begin, RandomAccessIterator end) { + std::make_heap(begin, end); + std::sort_heap(begin, end); +} + +// Full code + +#include <vector> + +using namespace std; + +void shift_down(vector<int>& heap,int i, int max) { + int i_big, c1, c2; + while(i < max) { + i_big = i; + c1 = (2*i) + 1; + c2 = c1 + 1; + if( c1<max && heap[c1]>heap[i_big] ) + i_big = c1; + if( c2<max && heap[c2]>heap[i_big] ) + i_big = c2; + if(i_big == i) return; + swap(heap[i],heap[i_big]); + i = i_big; + } +} + +void to_heap(vector<int>& arr) { + int i = (arr.size()/2) - 1; + while(i >= 0) { + shift_down(arr, i, arr.size()); + --i; + } +} + +void heap_sort(vector<int>& arr) { + to_heap(arr); + int end = arr.size() - 1; + while (end > 0) { + swap(arr[0], arr[end]); + shift_down(arr, 0, end); + --end; + } +} diff --git a/C++/Sorting/Quicksort.cpp b/C++/Sorting/Quicksort.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d71423d8ea79260fc33b2ebb1937d86a52219776 --- /dev/null +++ b/C++/Sorting/Quicksort.cpp @@ -0,0 +1,15 @@ +#include <iterator> +#include <algorithm> // for std::partition + +template<typename RandomAccessIterator, + typename Order> + void quicksort(RandomAccessIterator first, RandomAccessIterator last, Order order) +{ + if (last - first > 1) + { + RandomAccessIterator split = std::partition(first+1, last, std::bind2nd(order, *first)); + std::iter_swap(first, split-1); + quicksort(first, split-1, order); + quicksort(split, last, order); + } +} diff --git a/C/Sorting/Heapsort.c b/C/Sorting/Heapsort.c new file mode 100644 index 0000000000000000000000000000000000000000..b2e0ac013b580e11c007be55bed028c33fbcae87 --- /dev/null +++ b/C/Sorting/Heapsort.c @@ -0,0 +1,39 @@ +// Basic heapsort implimentation + +// Returns the maximum of parent and their children in the array +int max (int *a, int n, int i, int j, int k) { + int m = i; + if (j < n && a[j] > a[m]) { + m = j; + } + if (k < n && a[k] > a[m]) { + m = k; + } + return m; +} + +void downheap (int *a, int n, int i) { + while (1) { + int j = max(a, n, i, 2 * i + 1, 2 * i + 2); + if (j == i) { + break; + } + int t = a[i]; + a[i] = a[j]; + a[j] = t; + i = j; + } +} + +void heapsort (int *a, int n) { + int i; + for (i = (n - 2) / 2; i >= 0; i--) { + downheap(a, n, i); + } + for (i = 0; i < n; i++) { + int t = a[n - i - 1]; + a[n - i - 1] = a[0]; + a[0] = t; + downheap(a, n - i - 1, 0); + } +} diff --git a/C/Sorting/Quicksort.c b/C/Sorting/Quicksort.c new file mode 100644 index 0000000000000000000000000000000000000000..190360330b1a6744e8208a4108e68e220ec0f805 --- /dev/null +++ b/C/Sorting/Quicksort.c @@ -0,0 +1,24 @@ +// Quicksort algorithm +void quicksort(int *A, int len) +{ + if (len < 2) return; + + int pivot = A[len / 2]; + + int i, j; + for (i = 0, j = len - 1; ; i++, j--) + { + while (A[i] < pivot) i++; + while (A[j] > pivot) j--; + + if (i >= j) break; + + // swap + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + quicksort(A, i); + quicksort(A + i, len - i); +} diff --git a/Pseudocode/Sorting/Heapsort.md b/Pseudocode/Sorting/Heapsort.md new file mode 100644 index 0000000000000000000000000000000000000000..e0e32ce3333e4709c190c89d61210c4e9e578688 --- /dev/null +++ b/Pseudocode/Sorting/Heapsort.md @@ -0,0 +1,59 @@ +# Heapsort +## Complexity of O(`nlog(n)`) + +The basic idea is to turn the array into a binary heap structure, which has the property that it allows efficient retrieval and removal of the maximal element. + +We repeatedly "remove" the maximal element from the heap, thus building the sorted list from back to front. + +Heapsort requires random access, so can only be used on an array-like data structure. + +``` +function heapSort(a, count) is + input: an unordered array a of length count + + (first place a in max-heap order) + heapify(a, count) + + end := count - 1 + while end > 0 do + (swap the root(maximum value) of the heap with the + last element of the heap) + swap(a[end], a[0]) + (decrement the size of the heap so that the previous + max value will stay in its proper place) + end := end - 1 + (put the heap back in max-heap order) + siftDown(a, 0, end) + +function heapify(a,count) is + (start is assigned the index in a of the last parent node) + start := (count - 2) / 2 + + while start ≥ 0 do + (sift down the node at index start to the proper place + such that all nodes below the start index are in heap + order) + siftDown(a, start, count-1) + start := start - 1 + (after sifting down the root all nodes/elements are in heap order) + +function siftDown(a, start, end) is + (end represents the limit of how far down the heap to sift) + root := start + + while root * 2 + 1 ≤ end do (While the root has at least one child) + child := root * 2 + 1 (root*2+1 points to the left child) + (If the child has a sibling and the child's value is less than its sibling's...) + if child + 1 ≤ end and a[child] < a[child + 1] then + child := child + 1 (... then point to the right child instead) + if a[root] < a[child] then (out of max-heap order) + swap(a[root], a[child]) + root := child (repeat to continue sifting down the child now) + else + return +``` + +### Languages + * [Rust](../../Rust/Sorting/Heapsort.rs) + * [C++](../../C++/Sorting/Heapsort.cpp) + * [C](../../C/Sorting/Heapsort.c) diff --git a/Pseudocode/Sorting/Mergesort.md b/Pseudocode/Sorting/Mergesort.md new file mode 100644 index 0000000000000000000000000000000000000000..c821d69f9d9dfcfad6413b02d0b12d4a76a5b59c --- /dev/null +++ b/Pseudocode/Sorting/Mergesort.md @@ -0,0 +1,48 @@ +# Mergesort +## Complexity of O(`nlog(n)`) + +The basic idea is to split the collection into smaller groups by halving it until the groups only have one element or no elements (which are both entirely sorted groups). + +Then merge the groups back together so that their elements are in order. + +As such, the algorithm has two parts, the sorting function and the merging function. + +``` +function mergesort(m) + var list left, right, result + if length(m) ≤ 1 + return m + else + var middle = length(m) / 2 + for each x in m up to middle - 1 + add x to left + for each x in m at and after middle + add x to right + left = mergesort(left) + right = mergesort(right) + if last(left) ≤ first(right) + append right to left + return left + result = merge(left, right) + return result + +function merge(left,right) + var list result + while length(left) > 0 and length(right) > 0 + if first(left) ≤ first(right) + append first(left) to result + left = rest(left) + else + append first(right) to result + right = rest(right) + if length(left) > 0 + append rest(left) to result + if length(right) > 0 + append rest(right) to result + return result +``` + +### Languages + * [Rust](../../Rust/Sorting/Mergesort.rs) + * [C++](../../C++/Sorting/Mergesort.cpp) + * [C](../../C/Sorting/Mergesort.c)