Browse Source

Added quickSort.

Branimir Karadžić 8 years ago
parent
commit
8c0cdc361b
4 changed files with 126 additions and 7 deletions
  1. 15 4
      include/bx/sort.h
  2. 3 3
      include/bx/sort.inl
  3. 55 0
      src/sort.cpp
  4. 53 0
      tests/sort_test.cpp

+ 15 - 4
include/bx/radixsort.h → include/bx/sort.h

@@ -3,13 +3,24 @@
  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  */
 
-#ifndef BX_RADIXSORT_H_HEADER_GUARD
-#define BX_RADIXSORT_H_HEADER_GUARD
+#ifndef BX_SORT_H_HEADER_GUARD
+#define BX_SORT_H_HEADER_GUARD
 
 #include "bx.h"
 
 namespace bx
 {
+	///
+	typedef int32_t (*ComparisonFn)(const void* _lhs, const void* _rhs);
+
+	///
+	void quickSort(
+		  void* _data
+		, uint32_t _num
+		, uint32_t _stride
+		, const ComparisonFn _fn
+		);
+
 	///
 	void radixSort(
 		  uint32_t* __restrict _keys
@@ -46,6 +57,6 @@ namespace bx
 
 } // namespace bx
 
-#include "radixsort.inl"
+#include "sort.inl"
 
-#endif // BX_RADIXSORT_H_HEADER_GUARD
+#endif // BX_SORT_H_HEADER_GUARD

+ 3 - 3
include/bx/radixsort.inl → include/bx/sort.inl

@@ -3,9 +3,9 @@
  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  */
 
-#ifndef BX_RADIXSORT_H_HEADER_GUARD
-#	error "Must be included from bx/radixsort.h!"
-#endif // BX_RADIXSORT_H_HEADER_GUARD
+#ifndef BX_SORT_H_HEADER_GUARD
+#	error "Must be included from bx/sort.h!"
+#endif // BX_SORT_H_HEADER_GUARD
 
 namespace bx
 {

+ 55 - 0
src/sort.cpp

@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/sort.h>
+
+namespace bx
+{
+	static void quickSortR(void* _pivot, void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+	{
+		if (2 > _num)
+		{
+			return;
+		}
+
+		memCopy(_pivot, _data, _stride);
+
+		uint8_t* data = (uint8_t*)_data;
+
+		uint32_t ll = 0;
+		uint32_t gg = 1;
+
+		for (uint32_t ii = 1; ii < _num;)
+		{
+			int32_t result = _fn(&data[ii*_stride], _pivot);
+			if (0 > result)
+			{
+				xchg(&data[ll*_stride], &data[ii*_stride], _stride);
+				++ll;
+			}
+			else if (0 == result)
+			{
+				xchg(&data[gg*_stride], &data[ii*_stride], _stride);
+				++gg;
+				++ii;
+			}
+			else
+			{
+				++ii;
+			}
+		}
+
+		quickSortR(_pivot, &data[0         ], ll,      _stride, _fn);
+		quickSortR(_pivot, &data[gg*_stride], _num-gg, _stride, _fn);
+	}
+
+	void quickSort(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn)
+	{
+		uint8_t pivot[_stride];
+		quickSortR(pivot, _data, _num, _stride, _fn);
+	}
+
+} // namespace bx
+

+ 53 - 0
tests/sort_test.cpp

@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include "test.h"
+#include <bx/sort.h>
+#include <bx/string.h>
+#include <bx/rng.h>
+
+TEST_CASE("quickSort", "")
+{
+	const char* str[] =
+	{
+		"jabuka",
+		"kruska",
+		"malina",
+		"jagoda",
+	};
+
+	bx::quickSort(str, BX_COUNTOF(str), sizeof(void*)
+		, [](const void* _lhs, const void* _rhs)
+		{
+			const char* lhs = *(const char**)_lhs;
+			const char* rhs = *(const char**)_rhs;
+			return bx::strncmp(lhs, rhs);
+		});
+
+	REQUIRE(0 == bx::strncmp(str[0], "jabuka") );
+	REQUIRE(0 == bx::strncmp(str[1], "jagoda") );
+	REQUIRE(0 == bx::strncmp(str[2], "kruska") );
+	REQUIRE(0 == bx::strncmp(str[3], "malina") );
+
+	int8_t byte[128];
+	bx::RngMwc rng;
+	for (uint32_t ii = 0; ii < BX_COUNTOF(byte); ++ii)
+	{
+		byte[ii] = rng.gen()&0xff;
+	}
+
+	bx::quickSort(byte, BX_COUNTOF(byte), 1
+		, [](const void* _lhs, const void* _rhs)
+		{
+			int8_t lhs = *(const int8_t*)_lhs;
+			int8_t rhs = *(const int8_t*)_rhs;
+			return lhs - rhs;
+		});
+
+	for (uint32_t ii = 1; ii < BX_COUNTOF(byte); ++ii)
+	{
+		REQUIRE(byte[ii-1] <= byte[ii]);
+	}
+}