From bdfd0e8e2f8748283d5624e09f182b38e9128dee Mon Sep 17 00:00:00 2001 From: Tommoa <tommoa256@gmail.com> Date: Thu, 6 Apr 2017 22:54:02 +0800 Subject: [PATCH] Added Rust examples and fixed Quicksort.md --- Pseudocode/Sorting/Quicksort.md | 4 +-- Rust/Sorting/Heapsort.rs | 45 +++++++++++++++++++++++++++++++++ Rust/Sorting/Quicksort.rs | 31 +++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 Rust/Sorting/Heapsort.rs create mode 100644 Rust/Sorting/Quicksort.rs diff --git a/Pseudocode/Sorting/Quicksort.md b/Pseudocode/Sorting/Quicksort.md index 26a51fa..b6144d4 100644 --- a/Pseudocode/Sorting/Quicksort.md +++ b/Pseudocode/Sorting/Quicksort.md @@ -20,7 +20,7 @@ function quicksort(array) quicksort(less) quicksort(greater) array := concatenate(less, equal, greater) - ``` +``` A better quicksort algorithm works in place, by swapping elements within the array, to avoid the memory allocation of more arrays. ``` function quicksort(array) @@ -39,7 +39,7 @@ function quicksort(array) right := right - 1 quicksort(array from first index to right) quicksort(array from left to last index) - ``` +``` Quicksort is often compared to Mergesort as they both have an average time complexity of O(nlogn). According to the perldoc: > On average, mergesort does fewer comparisons than quicksort, so it may be better when complicated comparison routines are used. Mergesort also takes advantage of pre-existing order, so it would be favored for using sort() to merge several sorted arrays. On the other hand, quicksort is often faster for small arrays, and on arrays of a few distinct values, repeated many times. diff --git a/Rust/Sorting/Heapsort.rs b/Rust/Sorting/Heapsort.rs new file mode 100644 index 0000000..fe57593 --- /dev/null +++ b/Rust/Sorting/Heapsort.rs @@ -0,0 +1,45 @@ +// Using stdlib + +use std::collections::BinaryHeap; + +fn main() { + let src = vec![6,2,3,6,1,2,7,8,3,2]; + let sorted= BinaryHeap::from(src).into_sorted_vec(); + println!("{:?}", sorted); +} + +// Full code + +fn heap_sort<T,F>(array: &mut [T], order: F) + where F: Fn(&T,&T) -> bool +{ + let len = array.len(); + // Create heap + for start in (0..len/2).rev() { + sift_down(array,&order,start,len-1) + } + + for end in (1..len).rev() { + array.swap(0,end); + sift_down(array,&order,0,end-1) + } +} + +fn sift_down<T,F>(array: &mut [T], order: &F, start: usize, end: usize) + where F: Fn(&T,&T) -> bool +{ + let mut root = start; + loop { + let mut child = root * 2 + 1; + if child > end { break; } + if child + 1 <= end && order(&array[child], &array[child + 1]) { + child += 1; + } + if order(&array[root], &array[child]) { + array.swap(root,child); + root = child + } else { + break; + } + } +} diff --git a/Rust/Sorting/Quicksort.rs b/Rust/Sorting/Quicksort.rs new file mode 100644 index 0000000..65c9e14 --- /dev/null +++ b/Rust/Sorting/Quicksort.rs @@ -0,0 +1,31 @@ +// First argument is the array. Second argument is a comparison function +fn quick_sort<T,F>(v: &mut [T], f: &F) + where F: Fn(&T,&T) -> bool +{ + let len = v.len(); + if len >= 2 { + let pivot_index = partition(v, f); + quick_sort(&mut v[0..pivot_index], f); + quick_sort(&mut v[pivot_index + 1..len], f); + } +} + +fn partition<T,F>(v: &mut [T], f: &F) -> usize + where F: Fn(&T,&T) -> bool +{ + let len = v.len(); + let pivot_index = len / 2; + + v.swap(pivot_index, len - 1); + + let mut store_index = 0; + for i in 0..len - 1 { + if f(&v[i], &v[len - 1]) { + v.swap(i, store_index); + store_index += 1; + } + } + + v.swap(store_index, len - 1); + store_index +} -- GitLab