Skip to content
This repository
Browse code

added radix sort

  • Loading branch information...
commit 0b7a9added18127b4c4217a0639206dae6f09d0f 1 parent f3edd51
Heng Li authored June 06, 2012

Showing 1 changed file with 103 additions and 0 deletions. Show diff stats Hide diff stats

  1. 103  test/ksort_test.cc
103  test/ksort_test.cc
@@ -568,6 +568,92 @@ int * tmpArray;
568 568
  * END OF PAUL'S IMPLEMENTATION *
569 569
  ********************************/
570 570
 
  571
+#define rstype_t uint32_t
  572
+#define rskey(x) (x)
  573
+
  574
+#define RS_MIN_SIZE 63
  575
+
  576
+typedef struct {
  577
+	rstype_t *b, *e;
  578
+} bucket_t;
  579
+
  580
+static inline void rs_insertsort(rstype_t *s, rstype_t *t)
  581
+{
  582
+	rstype_t *i, *j, swap_tmp;
  583
+	for (i = s + 1; i < t; ++i)
  584
+		for (j = i; j > s && rskey(*j) < rskey(*(j-1)); --j) {
  585
+			swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp;
  586
+		}
  587
+}
  588
+
  589
+void rs_combsort(size_t n, rstype_t a[])
  590
+{
  591
+	const double shrink_factor = 1. / 1.2473309501039786540366528676643;
  592
+	int do_swap;
  593
+	size_t gap = n;
  594
+	rstype_t tmp, *i, *j;
  595
+	do {
  596
+		if (gap > 2) {
  597
+			gap = (size_t)(gap * shrink_factor);
  598
+			if (gap == 9 || gap == 10) gap = 11;
  599
+		}
  600
+		do_swap = 0;
  601
+		for (i = a; i < a + n - gap; ++i) {
  602
+			j = i + gap;
  603
+			if (rskey(*j) < rskey(*i)) {
  604
+				tmp = *i; *i = *j; *j = tmp;
  605
+				do_swap = 1;
  606
+			}
  607
+		}
  608
+	} while (do_swap || gap > 2);
  609
+	if (gap != 1) rs_insertsort(a, a + n);
  610
+}
  611
+
  612
+void rs_classify(rstype_t *beg, rstype_t *end, int n_bits, int s, bucket_t *b)
  613
+{
  614
+	rstype_t *i, tmp;
  615
+	int m = (1<<n_bits) - 1;
  616
+	bucket_t *k, *l, *be;
  617
+
  618
+	be = b + (1<<n_bits);
  619
+	for (k = b; k != be; ++k) k->b = k->e = beg;
  620
+	for (i = beg; i != end; ++i) ++b[rskey(*i)>>s&m].e;
  621
+	if (b[0].e == end) return; // no need to sort
  622
+	for (k = b + 1; k != be; ++k)
  623
+		k->e += (k-1)->e - beg, k->b = (k-1)->e;
  624
+	for (k = b; k != be;) {
  625
+		if (k->b == k->e) { ++k; continue; }
  626
+		l = b + (rskey(*k->b)>>s&m);
  627
+		if (k == l) { ++k->b; continue; }
  628
+		while (b + (rskey(*l->b)>>s&m) == l) ++l->b;
  629
+		tmp = *l->b; *l->b++ = *k->b; *k->b = tmp;
  630
+	}
  631
+	for (k = b + 1; k != be; ++k) k->b = (k-1)->e;
  632
+	b->b = beg;
  633
+}
  634
+
  635
+void rs_sort(rstype_t *beg, rstype_t *end, int n_bits, int s)
  636
+{
  637
+	if (end - beg < 2) { // already sorted
  638
+		return;
  639
+	} else if (end - beg > RS_MIN_SIZE) {
  640
+		bucket_t *b;
  641
+		int i;
  642
+		b = (bucket_t*)malloc(sizeof(bucket_t) * (1<<n_bits));
  643
+		rs_classify(beg, end, n_bits, s, b);
  644
+		if (s) {
  645
+			s = s > n_bits? s - n_bits : 0;
  646
+			for (i = 0; i != 1<<n_bits; ++i)
  647
+				if (b[i].e > b[i].b + 1) rs_sort(b[i].b, b[i].e, n_bits, s);
  648
+		}
  649
+		free(b);
  650
+	} else rs_combsort(end - beg, beg);
  651
+}
  652
+
  653
+/*************************
  654
+ *** END OF RADIX SORT ***
  655
+ *************************/
  656
+
571 657
 struct intcmp_t {
572 658
 	inline int operator() (int a, int b) const {
573 659
 		return a < b? -1 : a > b? 1 : 0;
@@ -596,6 +682,23 @@ int main(int argc, char *argv[])
596 682
 	srand48(11);
597 683
 	for (i = 0; i < N; ++i) array[i] = (int)lrand48();
598 684
 	t1 = clock();
  685
+	rs_sort((uint32_t*)array, (uint32_t*)array + N, 8, 24);
  686
+	t2 = clock();
  687
+	fprintf(stderr, "radix sort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC);
  688
+	for (i = 0; i < N-1; ++i) {
  689
+		if (array[i] > array[i+1]) {
  690
+			fprintf(stderr, "Bug in radix sort!\n");
  691
+			exit(1);
  692
+		}
  693
+	}
  694
+	t1 = clock();
  695
+	rs_sort((uint32_t*)array, (uint32_t*)array + N, 8, 24);
  696
+	t2 = clock();
  697
+	fprintf(stderr, "radix sort (sorted): %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC);
  698
+
  699
+	srand48(11);
  700
+	for (i = 0; i < N; ++i) array[i] = (int)lrand48();
  701
+	t1 = clock();
599 702
 	sort(array, array+N);
600 703
 	t2 = clock();
601 704
 	fprintf(stderr, "STL introsort: %.3lf\n", (double)(t2-t1)/CLOCKS_PER_SEC);

0 notes on commit 0b7a9ad

Please sign in to comment.
Something went wrong with that request. Please try again.