aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2024-06-23 21:23:01 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2024-07-17 20:10:56 +0100
commit894f79581f1717cb1edbef481ba17319f76dee51 (patch)
tree7461f729c0f78305043fe2a67c838a2d92df719e
parent6d21bce57be8440b56df10fe5d0ae7bd7e86037a (diff)
downloadalgorithms-894f79581f1717cb1edbef481ba17319f76dee51.tar.gz
algorithms-894f79581f1717cb1edbef481ba17319f76dee51.tar.bz2
algorithms-894f79581f1717cb1edbef481ba17319f76dee51.zip
New file for quicksort algorithm
-rw-r--r--impls/powerset.rkt14
-rw-r--r--qsort.cpp100
2 files changed, 107 insertions, 7 deletions
diff --git a/impls/powerset.rkt b/impls/powerset.rkt
index bbece52..5578312 100644
--- a/impls/powerset.rkt
+++ b/impls/powerset.rkt
@@ -27,13 +27,13 @@
;; Print success of test (i.e. (equality expected got)) and return a
;; boolean representing if it worked.
(printf "[TEST ~a]: " name)
- (if (equality expected got)
- (begin
- (displayln "Success")
- #t)
- (begin
- (printf "Failure (expected=~a, got=~a)~n" expected got)
- #f)))
+ (cond
+ [(equality expected got)
+ (displayln "Success")
+ #t]
+ [else
+ (printf "Failure (expected=~a, got=~a)~n" expected got)
+ #f]))
(define-syntax (perform-tests stx)
(with-syntax
diff --git a/qsort.cpp b/qsort.cpp
new file mode 100644
index 0000000..d3e8c1d
--- /dev/null
+++ b/qsort.cpp
@@ -0,0 +1,100 @@
+/* qsort.cpp
+ * Date: 2024-06-22
+ * Author: Aryadev Chavali
+ * Commentary: The inplace O(nlog(n)) sortitng algorithm. Originally designed
+ * in C, hence the lack of iostream.
+ */
+#include <cstdio>
+#include <cstdlib>
+
+#define ARR_SIZE(XS) (sizeof(XS) / sizeof((XS)[0]))
+#define SWAP(A, B) \
+ do \
+ { \
+ (A) ^= (B); \
+ (B) ^= (A); \
+ (A) ^= (B); \
+ } while (0)
+
+#define TEST_SIZE 20
+
+void print_arr(int *arr, int size)
+{
+ printf("{");
+ for (int i = 0; i < size - 1; ++i)
+ printf("%d, ", arr[i]);
+ printf("%d}", arr[size - 1]);
+}
+
+void quicksort(int *arr, int arr_size)
+{
+#ifdef TRACE
+ printf("before, arr=");
+ print_arr(arr, arr_size);
+ printf("\n");
+#endif
+ // Optimisation: for small arr_size, a different sort like the
+ // bubble sort may be better, instead of initialising new stack
+ // frames.
+ if (arr_size < 2)
+ return;
+ // Optimisation: Use some heuristics to figure out a better pivot
+ // than some constant choice of element.
+ int pivot = 0;
+ int pivot_value = arr[0];
+ for (int i = 1; i < arr_size; ++i)
+ {
+ if (arr[i] <= pivot_value)
+ {
+ if (i != pivot)
+ SWAP(arr[i], arr[pivot]);
+ ++pivot;
+ }
+ }
+
+#ifdef TRACE
+ printf("after, arr=");
+ print_arr(arr, arr_size);
+ printf("\n");
+#endif
+ // Optimisation: Use a stack to do this instead of recursion.
+ //
+ // This algorithm is similar to a pre order traversal/dfs, in this
+ // case on an array where left and right partition are children
+ // nodes to the original array node. Also with recursion there's a
+ // real risk for very large ARR_SIZE of running out of space in the
+ // call stack.
+ if (pivot != 0)
+ quicksort(arr, pivot);
+ if (pivot < arr_size - 1)
+ quicksort(arr + pivot + 1, arr_size - pivot - 1);
+}
+
+int main(void)
+{
+ int arr[TEST_SIZE] = {0};
+ const int size = TEST_SIZE;
+
+ // Generate a completely reverse ordered list
+ /*for (size_t i = 0; i < size; ++i) */
+ /* arr[TEST_SIZE - i - 1] = i;*/
+
+ // Generate a list where the first half is completely sorted and the
+ // other half is in reverse order.
+ for (size_t i = 0; i < size / 2; ++i)
+ arr[i] = i;
+ for (size_t i = size / 2; i < size; ++i)
+ arr[TEST_SIZE - (i - size / 2) - 1] = i;
+
+ printf("Before: ");
+ print_arr(arr, size);
+ printf("\n");
+
+ quicksort(arr, size);
+
+ printf("After: ");
+ print_arr(arr, size);
+ printf("\n");
+
+ return 0;
+}