The burstsort4j package contains the generally interesting
15 | classes, namely Burstsort, which implements the original
16 | Burstsort algorithm. The package also contains a multikey quicksort
17 | implementation, as used by burstsort, as well as a basic quicksort
18 | and insertionsort.
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/benchmark/BenchmarkResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j.benchmark;
7 |
8 | /**
9 | * Data regarding the run of a benchmark, including the number of
10 | * iterations and the number of nanoseconds per iteration.
11 | *
12 | * @author Nathan Fiedler
13 | */
14 | public class BenchmarkResult {
15 |
16 | private final int count;
17 | private final long ns;
18 |
19 | BenchmarkResult(int count, long ns) {
20 | this.count = count;
21 | this.ns = ns;
22 | }
23 |
24 | public int count() {
25 | return count;
26 | }
27 |
28 | public long nsPerOp() {
29 | if (count <= 0) {
30 | return 0;
31 | }
32 | return ns / count;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/benchmark/DataGeneratorTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j.benchmark;
7 |
8 | import org.burstsort4j.Quicksort;
9 | import org.junit.Test;
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Unit tests for the DataGenerator class.
14 | *
15 | * @author Nathan Fiedler
16 | */
17 | public class DataGeneratorTest {
18 |
19 | @Test
20 | public void testMedianOf3Killer() {
21 | DataGenerator generator = DataGenerator.MEDIAN_OF_3_KILLER;
22 | String[] results = generator.generate(DataSize.N_20);
23 | String[] sorted = new String[results.length];
24 | System.arraycopy(results, 0, sorted, 0, results.length);
25 | Quicksort.sort(sorted);
26 | int[] order = new int[]{0, 10, 2, 12, 4, 14, 6, 16, 8, 18,
27 | 1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
28 | assertEquals(order.length, results.length);
29 | for (int ii = 0; ii < order.length; ii++) {
30 | assertEquals(sorted[order[ii]], results[ii]);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Gnomesort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * Implementation of Gnome sort based on pseudocode on Wikipedia.
10 | *
11 | * @author Nathan Fiedler
12 | */
13 | public class Gnomesort {
14 |
15 | private Gnomesort() {
16 | }
17 |
18 | /**
19 | * Sort the input array using the Gnome sort algorithm.
20 | * O(n^2) running time.
21 | *
22 | * @param type of comparable to be sorted.
23 | * @param input array of comparable objects to be sorted.
24 | */
25 | public static > void sort(T[] input) {
26 | if (input == null || input.length < 2) {
27 | return;
28 | }
29 | int i = 1;
30 | int j = 2;
31 | while (i < input.length) {
32 | if (input[i - 1].compareTo(input[i]) < 1) {
33 | i = j;
34 | j++;
35 | } else {
36 | // swap a[i-1] and a[i]
37 | T t = input[i - 1];
38 | input[i - 1] = input[i];
39 | input[i] = t;
40 | i--;
41 | if (i == 0) {
42 | i = j;
43 | j++;
44 | }
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Shellsort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * Shell sort implementation based on pseudocode from Wikipedia.
10 | *
11 | * @author Nathan Fiedler
12 | */
13 | public class Shellsort {
14 |
15 | private Shellsort() {
16 | }
17 |
18 | /**
19 | * Sort the input array using the shell sort algorithm with the gap
20 | * sequence suggested by Gonnet and Baeza-Yates.
21 | *
22 | * @param type of comparable to be sorted.
23 | * @param input array of comparable objects to be sorted.
24 | */
25 | public static > void sort(T[] input) {
26 | if (input == null || input.length < 2) {
27 | return;
28 | }
29 |
30 | int inc = input.length / 2;
31 | while (inc > 0) {
32 | for (int ii = inc; ii < input.length; ii++) {
33 | T temp = input[ii];
34 | int jj = ii;
35 | while (jj >= inc && input[jj - inc].compareTo(temp) > 0) {
36 | input[jj] = input[jj - inc];
37 | jj -= inc;
38 | }
39 | input[jj] = temp;
40 | }
41 | // Another way of dividing by 2.2 to get an integer.
42 | inc = inc == 2 ? 1 : inc * 5 / 11;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011 Nathan Fiedler. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above
10 | copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the
12 | distribution.
13 | * Neither the name of Nathan Fiedler nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Combsort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * Implementation of comb sort based on pseudo-code on Wikipedia,
10 | * in particular the Combsort11 algorithm.
11 | *
12 | * @author Nathan Fiedler
13 | */
14 | public class Combsort {
15 |
16 | private Combsort() {
17 | }
18 |
19 | /**
20 | * Sort the input array using the Combsort11 algorithm.
21 | * Purportedly O(n*logn) running time.
22 | *
23 | * @param type of comparable to be sorted.
24 | * @param input array of comparable objects to be sorted.
25 | */
26 | public static > void sort(T[] input) {
27 | if (input == null || input.length < 2) {
28 | return;
29 | }
30 |
31 | int gap = input.length; //initialize gap size
32 | boolean swapped = true;
33 |
34 | while (gap > 1 || swapped) {
35 | // Update the gap value for the next comb.
36 | if (gap > 1) {
37 | gap = (gap * 10) / 13;
38 | if (gap == 10 || gap == 9) {
39 | gap = 11;
40 | }
41 | }
42 |
43 | swapped = false;
44 |
45 | // a single "comb" over the input list
46 | for (int i = 0; i + gap < input.length; i++) {
47 | int j = i + gap;
48 | if (input[i].compareTo(input[j]) > 0) {
49 | T tmp = input[i];
50 | input[i] = input[j];
51 | input[j] = tmp;
52 | // Signal that the list is not guaranteed sorted.
53 | swapped = true;
54 | }
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/HybridCombsort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * An implementation of comb sort that delegates to insertion sort when
10 | * the gap value has dropped below a certain threshold. This variation
11 | * was proposed by David B. Ring of Palo Alto and demonstrated to be
12 | * 10 to 15 percent faster than traditional comb sort. This particular
13 | * implementation uses the Combsort11 variation for determining the
14 | * gap values.
15 | *
16 | * @author Nathan Fiedler
17 | */
18 | public class HybridCombsort {
19 |
20 | private HybridCombsort() {
21 | }
22 |
23 | /**
24 | * Sort the input array using a hybrid of Combsort11 and Insertion sort.
25 | *
26 | * @param type of comparable to be sorted.
27 | * @param input array of comparable objects to be sorted.
28 | */
29 | public static > void sort(T[] input) {
30 | if (input == null || input.length < 2) {
31 | return;
32 | }
33 |
34 | int gap = input.length;
35 | while (gap > 8) {
36 | gap = (10 * gap) / 13;
37 | if (gap == 10 || gap == 9) {
38 | gap = 11;
39 | }
40 | for (int i = 0; i + gap < input.length; i++) {
41 | int j = i + gap;
42 | if (input[i].compareTo(input[j]) > 0) {
43 | T tmp = input[i];
44 | input[i] = input[j];
45 | input[j] = tmp;
46 | }
47 | }
48 | }
49 | // At this point the input is nearly sorted, a case for which
50 | // insertion sort performs very well.
51 | Insertionsort.sort(input);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Burstsort ##
2 |
3 | Burstsort4j contains an implementation of both the original
4 | [Burstsort](http://en.wikipedia.org/wiki/Burstsort), which is quite fast
5 | but not particularly memory efficient, and the engineered Burstsort, which
6 | is extremely memory efficient and close to the speed of the original in
7 | most cases. Burstsort typically outperforms other string sorting algorithms
8 | for most data sets.
9 |
10 | Both single-threaded and multi-threaded implementations are available,
11 | where the multi-threaded method will utilize all available processor cores
12 | using a simple thread pool executor. In this mode of operation, the buckets
13 | to be sorted are assigned to jobs and sorted in parallel.
14 |
15 | ## Funnelsort ##
16 |
17 | In addition to Burstsort there is an implementation of the Funnelsort
18 | algorithm for sorting strings, which is faster than most string sorts but
19 | not as fast as Burstsort. Funnelsort uses string comparison while Burstsort
20 | is a form of radix sort and hence sorts only lexicographically by
21 | individual characters. The specific implementation of Funnelsort is modeled
22 | after the [Lazy Funnelsort](http://portal.acm.org/citation.cfm?id=1227161.1227164)
23 | described by Brodal, Fagerberg, and Vinther. At the heart of the algorithm
24 | is an [insertion d-way merger](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.63.3896)
25 | as described by Brodal and Moruz. Like Burstsort, the Funnelsort algorithm
26 | is cache- oblivious and thus typically performs well compared to algorithms
27 | that assume a unit-cost for RAM access (e.g. Quicksort).
28 |
29 | ## Multikey Quicksort ##
30 |
31 | Burstsort4j contains a Java implementation of the multikey quicksort
32 | algorithm. It takes a median of three approach to find the pivot, and
33 | delegates to insertion sort for small sublists. This sort is what Burstsort
34 | delegates to for sorting the buckets that hang from the trie structure.
35 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Selectionsort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * Basic selection sort implementation based on pseudocode on Wikipedia.
10 | *
11 | * @author Nathan Fiedler
12 | */
13 | public class Selectionsort {
14 |
15 | private Selectionsort() {
16 | }
17 |
18 | /**
19 | * Sort the input array using the selection sort algorithm.
20 | * O(n^2) running time.
21 | *
22 | * @param type of comparable to be sorted.
23 | * @param input array of comparable objects to be sorted.
24 | */
25 | public static > void sort(T[] input) {
26 | if (input != null && input.length > 1) {
27 | sort(input, 0, input.length - 1);
28 | }
29 | }
30 |
31 | /**
32 | * Sort the input array using the selection sort algorithm.
33 | * O(n^2) running time.
34 | *
35 | * @param type of comparable to be sorted.
36 | * @param input array of comparable objects to be sorted.
37 | * @param low low end of range to sort.
38 | * @param high high end of range to sort (inclusive).
39 | */
40 | public static > void sort(T[] input,
41 | int low, int high) {
42 | if (input == null || input.length < 2 || high <= low) {
43 | return;
44 | }
45 |
46 | for (int ii = low; ii < high; ii++) {
47 | int min = ii;
48 | for (int jj = ii + 1; jj < input.length; jj++) {
49 | if (input[jj].compareTo(input[min]) < 0) {
50 | min = jj;
51 | }
52 | }
53 | if (ii != min) {
54 | T temp = input[ii];
55 | input[ii] = input[min];
56 | input[min] = temp;
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/benchmark/DataSize.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j.benchmark;
7 |
8 | /**
9 | * Size of the data sets used in testing sort performance.
10 | * For the median-of-three killer generator to work, the
11 | * sizes must be divisible by four.
12 | *
13 | * @author Nathan Fiedler
14 | */
15 | public enum DataSize {
16 |
17 | N_12 {
18 |
19 | @Override
20 | public int getValue() {
21 | return 12;
22 | }
23 | },
24 | N_20 {
25 |
26 | @Override
27 | public int getValue() {
28 | return 20;
29 | }
30 | },
31 | N_52 {
32 |
33 | @Override
34 | public int getValue() {
35 | return 52;
36 | }
37 | },
38 | N_100 {
39 |
40 | @Override
41 | public int getValue() {
42 | return 100;
43 | }
44 | },
45 | N_400 {
46 |
47 | @Override
48 | public int getValue() {
49 | return 400;
50 | }
51 | },
52 | N_800 {
53 |
54 | @Override
55 | public int getValue() {
56 | return 800;
57 | }
58 | },
59 | N_1000 {
60 |
61 | @Override
62 | public int getValue() {
63 | return 1000;
64 | }
65 | },
66 | N_4000 {
67 |
68 | @Override
69 | public int getValue() {
70 | return 4000;
71 | }
72 | },
73 | N_16000 {
74 |
75 | @Override
76 | public int getValue() {
77 | return 16000;
78 | }
79 | },
80 | N_64000 {
81 |
82 | @Override
83 | public int getValue() {
84 | return 64000;
85 | }
86 | },
87 | N_256000 {
88 |
89 | @Override
90 | public int getValue() {
91 | return 256000;
92 | }
93 | },
94 | N_512000 {
95 |
96 | @Override
97 | public int getValue() {
98 | return 512000;
99 | }
100 | },
101 | N_1024000 {
102 |
103 | @Override
104 | public int getValue() {
105 | return 1024000;
106 | }
107 | },
108 | N_3000000 {
109 |
110 | @Override
111 | public int getValue() {
112 | return 3000000;
113 | }
114 | };
115 |
116 | /**
117 | * Returns the quantity for this data size.
118 | *
119 | * @return quantity.
120 | */
121 | public abstract int getValue();
122 | };
123 |
--------------------------------------------------------------------------------
/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | annotation.processing.enabled=true
2 | annotation.processing.enabled.in.editor=false
3 | annotation.processing.processors.list=
4 | annotation.processing.run.all.processors=true
5 | application.desc=Java implementations of cache-oblivious sorting algorithms.
6 | application.homepage=https://github.com/nlfiedler/burstsort4j/
7 | application.title=burstsort4j
8 | application.vendor=Nathan Fiedler
9 | auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
10 | build.classes.dir=${build.dir}/classes
11 | build.classes.excludes=**/*.java,**/*.form
12 | # This directory is removed when the project is cleaned:
13 | build.dir=build
14 | build.generated.dir=${build.dir}/generated
15 | build.generated.sources.dir=${build.dir}/generated-sources
16 | # Only compile against the classpath explicitly listed here:
17 | build.sysclasspath=ignore
18 | build.test.classes.dir=${build.dir}/test/classes
19 | build.test.results.dir=${build.dir}/test/results
20 | debug.classpath=\
21 | ${run.classpath}
22 | debug.test.classpath=\
23 | ${run.test.classpath}
24 | # This directory is removed when the project is cleaned:
25 | dist.dir=dist
26 | dist.jar=${dist.dir}/burstsort4j.jar
27 | dist.javadoc.dir=${dist.dir}/javadoc
28 | endorsed.classpath=
29 | excludes=
30 | includes=**
31 | jar.archive.disabled=${jnlp.enabled}
32 | jar.compress=false
33 | jar.index=${jnlp.enabled}
34 | javac.classpath=
35 | # Space-separated list of extra javac options
36 | javac.compilerargs=-Xlint
37 | javac.deprecation=true
38 | javac.processorpath=\
39 | ${javac.classpath}
40 | javac.source=1.7
41 | javac.target=1.7
42 | javac.test.classpath=\
43 | ${javac.classpath}:\
44 | ${build.classes.dir}:\
45 | ${libs.junit_4.classpath}
46 | javadoc.additionalparam=
47 | javadoc.author=false
48 | javadoc.encoding=${source.encoding}
49 | javadoc.noindex=false
50 | javadoc.nonavbar=false
51 | javadoc.notree=false
52 | javadoc.private=false
53 | javadoc.splitindex=true
54 | javadoc.use=true
55 | javadoc.version=false
56 | javadoc.windowtitle=Burstsort for Java
57 | jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
58 | jnlp.codebase.type=local
59 | jnlp.codebase.url=file:/Users/nfiedler/projects/burstsort4j/trunk/dist/
60 | jnlp.descriptor=application
61 | jnlp.enabled=false
62 | jnlp.mixed.code=default
63 | jnlp.offline-allowed=false
64 | jnlp.signed=false
65 | jnlp.signing=
66 | jnlp.signing.alias=
67 | jnlp.signing.keystore=
68 | main.class=org.burstsort4j.benchmark.MicroBenchmark
69 | # Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed
70 | manifest.custom.codebase=
71 | # Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
72 | manifest.custom.permissions=
73 | manifest.file=manifest.mf
74 | meta.inf.dir=${src.dir}/META-INF
75 | mkdist.disabled=false
76 | platform.active=default_platform
77 | project.license=default
78 | run.classpath=\
79 | ${javac.classpath}:\
80 | ${build.classes.dir}
81 | run.jvmargs=-server -Xmx2048m
82 | run.test.classpath=\
83 | ${javac.test.classpath}:\
84 | ${build.test.classes.dir}
85 | source.encoding=UTF-8
86 | src.dir=src
87 | test.src.dir=test
88 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/benchmark/BenchmarkData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j.benchmark;
7 |
8 | /**
9 | * The data regarding a benchmark, including the elapsed time and
10 | * a timer for tracking the current run.
11 | *
12 | * @author Nathan Fiedler
13 | */
14 | public class BenchmarkData {
15 |
16 | /** Number of nanoseconds in one second. */
17 | private static final int ONE_BILLION = 1000000000;
18 | private final BenchmarkRunnable func;
19 | private int count;
20 | private long start;
21 | private long ns;
22 |
23 | public BenchmarkData(BenchmarkRunnable r) {
24 | func = r;
25 | }
26 |
27 | public int count() {
28 | return count;
29 | }
30 |
31 | public void startTimer() {
32 | start = System.nanoTime();
33 | }
34 |
35 | public void stopTimer() {
36 | if (start > 0) {
37 | ns += System.nanoTime() - start;
38 | }
39 | start = 0;
40 | }
41 |
42 | public void resetTimer() {
43 | start = 0;
44 | ns = 0;
45 | }
46 |
47 | public long nsPerOp() {
48 | if (count <= 0) {
49 | return 0;
50 | }
51 | return ns / count;
52 | }
53 |
54 | private void runN(int n) {
55 | count = n;
56 | resetTimer();
57 | startTimer();
58 | func.run(this);
59 | stopTimer();
60 | }
61 |
62 | private int roundDown10(int n) {
63 | int tens = 0;
64 | while (n > 10) {
65 | n /= 10;
66 | tens++;
67 | }
68 | int result = 1;
69 | for (int i = 0; i < tens; i++) {
70 | result *= 10;
71 | }
72 | return result;
73 | }
74 |
75 | private int roundUp(int n) {
76 | int base = roundDown10(n);
77 | if (n < (2 * base)) {
78 | return 2 * base;
79 | }
80 | if (n < (5 * base)) {
81 | return 5 * base;
82 | }
83 | return 10 * base;
84 | }
85 |
86 | /**
87 | * Run the benchmark function a sufficient number of times to
88 | * get a timing of at least one second.
89 | *
90 | * @return the results of the benchmark run.
91 | */
92 | public BenchmarkResult run() {
93 | // This code is a translation of that found in the Go testing package.
94 | // Run the benchmark for a single iteration in case it's expensive.
95 | int n = 1;
96 | runN(n);
97 | // Run the benchmark for at least a second.
98 | while (ns < ONE_BILLION && n < ONE_BILLION) {
99 | int last = n;
100 | // Predict iterations/sec.
101 | if (nsPerOp() == 0) {
102 | n = ONE_BILLION;
103 | } else {
104 | n = ONE_BILLION / (int) nsPerOp();
105 | }
106 | // Run more iterations than we think we'll need for a second (1.5x).
107 | // Don't grow too fast in case we had timing errors previously.
108 | // Be sure to run at least one more than last time.
109 | n = Math.max(Math.min(n + n / 2, 100 * last), last + 1);
110 | // Round up to something easy to read.
111 | n = roundUp(n);
112 | runN(n);
113 | }
114 | return new BenchmarkResult(count, ns);
115 |
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Insertionsort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * Simple implementation of insertion sort algorithm. Used by the
10 | * multikey quicksort implementation for small subarrays.
11 | *
12 | * @author Nathan Fiedler
13 | */
14 | public class Insertionsort {
15 |
16 | private Insertionsort() {
17 | }
18 |
19 | /**
20 | * Sort the array of comparables. Uses a simple insertion sort
21 | * algorithm, so expect O(n^2) running time.
22 | *
23 | * @param type of comparable to be sorted.
24 | * @param arr comparables to be sorted.
25 | */
26 | public static > void sort(T[] arr) {
27 | if (arr != null) {
28 | sort(arr, 0, arr.length - 1);
29 | }
30 | }
31 |
32 | /**
33 | * Sort the array of comparables within the given range of elements.
34 | * Uses a simple insertion sort algorithm, so expect O(n^2) running
35 | * time.
36 | *
37 | * @param type of comparable to be sorted.
38 | * @param arr comparables to be sorted.
39 | * @param low low end of range to sort (inclusive).
40 | * @param high high end of range to sort (inclusive).
41 | */
42 | public static > void sort(T[] arr, int low, int high) {
43 | if (arr == null || arr.length < 2 || low < 0 || high <= low) {
44 | return;
45 | }
46 |
47 | for (int i = low + 1; i <= high; i++) {
48 | T pivot = arr[i];
49 | int j = i;
50 | while (j > low && pivot.compareTo(arr[j - 1]) < 0) {
51 | arr[j] = arr[j - 1];
52 | j--;
53 | }
54 | arr[j] = pivot;
55 | }
56 | }
57 |
58 | /**
59 | * Sort the strings in the array using an insertion sort, but only
60 | * consider the characters in the strings starting from the given
61 | * offset depth. That is, the method will ignore all characters
62 | * appearing before the depth character.
63 | *
64 | * @param strings array of strings to sort.
65 | * @param low low offset into the array (inclusive).
66 | * @param high high offset into the array (exclusive).
67 | * @param depth offset of first character in each string to compare.
68 | */
69 | public static void sort(CharSequence[] strings, int low, int high, int depth) {
70 | if (strings == null || low < 0 || high <= low || depth < 0) {
71 | return;
72 | }
73 | for (int i = low + 1; i < high; i++) {
74 | for (int j = i; j > low; j--) {
75 | int idx = depth;
76 | char s = idx < strings[j - 1].length() ? strings[j - 1].charAt(idx) : 0;
77 | char t = idx < strings[j].length() ? strings[j].charAt(idx) : 0;
78 | while (s == t && idx < strings[j - 1].length()) {
79 | idx++;
80 | s = idx < strings[j - 1].length() ? strings[j - 1].charAt(idx) : 0;
81 | t = idx < strings[j].length() ? strings[j].charAt(idx) : 0;
82 | }
83 | if (s <= t) {
84 | break;
85 | }
86 | CharSequence tmp = strings[j];
87 | strings[j] = strings[j - 1];
88 | strings[j - 1] = tmp;
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Heapsort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * Binary heap sort implementation based on pseudocode from Wikipedia.
10 | *
11 | * @author Nathan Fiedler
12 | */
13 | public class Heapsort {
14 |
15 | private Heapsort() {
16 | }
17 |
18 | /**
19 | * Sort the input array using the heap sort algorithm.
20 | * O(n*logn) running time with constant extra space.
21 | *
22 | * @param type of comparable to be sorted.
23 | * @param input array of comparable objects to be sorted.
24 | */
25 | public static > void sort(T[] input) {
26 | if (input == null || input.length < 2) {
27 | return;
28 | }
29 |
30 | // start is assigned the index in a of the last parent node
31 | for (int start = (input.length - 2) / 2; start >= 0; start--) {
32 | // sift down the node at index start to the proper place such
33 | // that all nodes below the start index are in heap order
34 | int root = start;
35 | // While the root has at least one child
36 | while (root * 2 + 1 < input.length) {
37 | // root*2+1 points to the left child
38 | int child = root * 2 + 1;
39 | // If the child has a sibling and the child's value
40 | // is less than its sibling's...
41 | if ((child + 1 < input.length) &&
42 | input[child].compareTo(input[child + 1]) < 0) {
43 | // ... then point to the right child instead
44 | child++;
45 | }
46 | // out of max-heap order
47 | if (input[root].compareTo(input[child]) < 0) {
48 | T temp = input[root];
49 | input[root] = input[child];
50 | input[child] = temp;
51 | // repeat to continue sifting down the child now
52 | root = child;
53 | } else {
54 | break;
55 | }
56 | }
57 | }
58 | // after sifting down the root all nodes/elements are in heap order
59 |
60 | for (int end = input.length - 1; end > 0; end--) {
61 | // swap the root (maximum value) of the heap with the last
62 | // element of the heap
63 | T temp = input[end];
64 | input[end] = input[0];
65 | input[0] = temp;
66 | // put the heap back in max-heap order
67 | int root = 0;
68 | // While the root has at least one child
69 | while (root * 2 + 1 < end) {
70 | // root*2+1 points to the left child
71 | int child = root * 2 + 1;
72 | // If the child has a sibling and the child's value is
73 | // less than its sibling's...
74 | if ((child + 1 < end) &&
75 | input[child].compareTo(input[child + 1]) < 0) {
76 | // ... then point to the right child instead
77 | child++;
78 | }
79 | // out of max-heap order
80 | if (input[root].compareTo(input[child]) < 0) {
81 | temp = input[root];
82 | input[root] = input[child];
83 | input[child] = temp;
84 | // repeat to continue sifting down the child now
85 | root = child;
86 | } else {
87 | break;
88 | }
89 | }
90 | // end of for loop decreases the size of the heap by one so that
91 | // the previous max value will stay in its proper placement
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Quicksort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | /**
9 | * This is the traditional quicksort algorithm. It is comparison-based,
10 | * which for strings, is considerably less efficient than a radix-based
11 | * sort, and in particular, multikey quicksort.
12 | *
13 | *
If you are sorting arrays of primitives, consider using the
14 | * java.util.Arrays class instead, which uses additional
15 | * heuristics to improve performance.
16 | *
17 | * @author Nathan Fiedler
18 | */
19 | public class Quicksort {
20 |
21 | /** As with GCC std::sort delegate to insertion sort for ranges of
22 | * size below 16. */
23 | private static final int THRESHOLD = 16;
24 |
25 | /**
26 | * Creates a new instance of Quicksort.
27 | */
28 | private Quicksort() {
29 | }
30 |
31 | /**
32 | * Sorts the given array of comparable objects using the standard
33 | * quicksort algorithm. This sort is not stable. The objects
34 | * are sorted in place with constant additional memory (not counting
35 | * the stack due to recursion).
36 | *
37 | * @param type of comparable to be sorted.
38 | * @param arr an array of Comparable items to sort.
39 | */
40 | public static > void sort(T[] arr) {
41 | if (arr != null && arr.length > 1) {
42 | sort(arr, 0, arr.length - 1);
43 | }
44 | }
45 |
46 | /**
47 | * Basic implementation of quicksort. Uses median-of-three partitioning
48 | * and a cutoff at which point insertion sort is used.
49 | *
50 | * @param type of comparable to be sorted.
51 | * @param arr an array of Comparable items.
52 | * @param low the left-most index of the subarray.
53 | * @param high the right-most index of the subarray.
54 | */
55 | public static > void sort(T[] arr, int low, int high) {
56 | if (low + THRESHOLD > high) {
57 | // Insertion sort for small partitions.
58 | Insertionsort.sort(arr, low, high);
59 | } else {
60 | // Choose a partition element
61 | int middle = (low + high) / 2;
62 | // Order the low, middle, and high elements
63 | if (arr[middle].compareTo(arr[low]) < 0) {
64 | swap(arr, low, middle);
65 | }
66 | if (arr[high].compareTo(arr[low]) < 0) {
67 | swap(arr, low, high);
68 | }
69 | if (arr[high].compareTo(arr[middle]) < 0) {
70 | swap(arr, middle, high);
71 | }
72 | // Place pivot element at the high end in preparation
73 | // for the ensuing swapping of elements.
74 | swap(arr, middle, high - 1);
75 | T pivot = arr[high - 1];
76 |
77 | // Order the elements such that those below the pivot
78 | // point appear earlier, and those higher than the pivot
79 | // appear later.
80 | int i = low;
81 | int j = high - 1;
82 | while (true) {
83 | while (arr[++i].compareTo(pivot) < 0) {
84 | }
85 | while (pivot.compareTo(arr[--j]) < 0) {
86 | }
87 | if (i >= j) {
88 | break;
89 | }
90 | swap(arr, i, j);
91 | }
92 |
93 | // Restore pivot element to its rightful position.
94 | swap(arr, i, high - 1);
95 | // Sort low partition recursively.
96 | sort(arr, low, i - 1);
97 | // Sort high partition recursively.
98 | sort(arr, i + 1, high);
99 | }
100 | }
101 |
102 | /**
103 | * Method to swap to elements in an array.
104 | *
105 | * @param a an array of objects.
106 | * @param x the index of the first object.
107 | * @param y the index of the second object.
108 | */
109 | private static void swap(Object[] a, int x, int y) {
110 | Object tmp = a[x];
111 | a[x] = a[y];
112 | a[y] = tmp;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/CombsortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the Combsort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class CombsortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | Combsort.sort((String[]) null);
26 | Combsort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | Combsort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | Combsort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | Combsort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | Combsort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | Combsort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testDictWords() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | String[] arr = data.toArray(new String[data.size()]);
53 | Combsort.sort(arr);
54 | assertTrue(Tests.isSorted(arr));
55 | } catch (IOException ioe) {
56 | fail(ioe.toString());
57 | }
58 | }
59 |
60 | @Test
61 | public void testSorted() {
62 | try {
63 | List data = Tests.loadData();
64 | Collections.sort(data);
65 | String[] arr = data.toArray(new String[data.size()]);
66 | Combsort.sort(arr);
67 | assertTrue(Tests.isSorted(arr));
68 | } catch (IOException ioe) {
69 | fail(ioe.toString());
70 | }
71 | }
72 |
73 | @Test
74 | public void testReversed() {
75 | try {
76 | List data = Tests.loadData();
77 | Collections.sort(data);
78 | Collections.reverse(data);
79 | String[] arr = data.toArray(new String[data.size()]);
80 | Combsort.sort(arr);
81 | assertTrue(Tests.isSorted(arr));
82 | } catch (IOException ioe) {
83 | fail(ioe.toString());
84 | }
85 | }
86 |
87 | @Test
88 | public void testRepeated() {
89 | String[] arr = new String[10000];
90 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
91 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
92 | Arrays.fill(arr, STR);
93 | Combsort.sort(arr);
94 | assertTrue(Tests.isRepeated(arr, STR));
95 | }
96 |
97 | @Test
98 | public void testRepeatedCycle() {
99 | String[] strs = new String[100];
100 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
101 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
102 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
103 | strs[i] = seed.substring(0, l);
104 | }
105 | List list = new ArrayList();
106 | for (int c = 10000, i = 0; c > 0; i++, c--) {
107 | list.add(strs[i % strs.length]);
108 | }
109 | String[] arr = list.toArray(new String[list.size()]);
110 | Combsort.sort(arr);
111 | assertTrue(Tests.isSorted(arr));
112 | }
113 |
114 | @Test
115 | public void testRandom() {
116 | List data = Tests.generateData(10000, 100);
117 | String[] arr = data.toArray(new String[data.size()]);
118 | Combsort.sort(arr);
119 | assertTrue(Tests.isSorted(arr));
120 | }
121 |
122 | @Test
123 | public void testHamlet() {
124 | try {
125 | List data = Tests.loadData("hamletwords");
126 | Collections.shuffle(data);
127 | String[] arr = data.toArray(new String[data.size()]);
128 | Combsort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | } catch (IOException ioe) {
131 | fail(ioe.toString());
132 | }
133 | }
134 |
135 | @Test
136 | public void testDictCalls() {
137 | try {
138 | List data = Tests.loadData("dictcalls.gz", true);
139 | String[] arr = data.toArray(new String[data.size()]);
140 | Combsort.sort(arr);
141 | assertTrue(Tests.isSorted(arr));
142 | } catch (IOException ioe) {
143 | fail(ioe.toString());
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/IntrosortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the Introsort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class IntrosortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | Introsort.sort((String[]) null);
26 | Introsort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | Introsort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | Introsort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | Introsort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | Introsort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | Introsort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testDictWords() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | String[] arr = data.toArray(new String[data.size()]);
53 | Introsort.sort(arr);
54 | assertTrue(Tests.isSorted(arr));
55 | } catch (IOException ioe) {
56 | fail(ioe.toString());
57 | }
58 | }
59 |
60 | @Test
61 | public void testSorted() {
62 | try {
63 | List data = Tests.loadData();
64 | Collections.sort(data);
65 | String[] arr = data.toArray(new String[data.size()]);
66 | Introsort.sort(arr);
67 | assertTrue(Tests.isSorted(arr));
68 | } catch (IOException ioe) {
69 | fail(ioe.toString());
70 | }
71 | }
72 |
73 | @Test
74 | public void testReversed() {
75 | try {
76 | List data = Tests.loadData();
77 | Collections.sort(data);
78 | Collections.reverse(data);
79 | String[] arr = data.toArray(new String[data.size()]);
80 | Introsort.sort(arr);
81 | assertTrue(Tests.isSorted(arr));
82 | } catch (IOException ioe) {
83 | fail(ioe.toString());
84 | }
85 | }
86 |
87 | @Test
88 | public void testRepeated() {
89 | String[] arr = new String[10000];
90 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
91 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
92 | Arrays.fill(arr, STR);
93 | Introsort.sort(arr);
94 | assertTrue(Tests.isRepeated(arr, STR));
95 | }
96 |
97 | @Test
98 | public void testRepeatedCycle() {
99 | String[] strs = new String[100];
100 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
101 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
102 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
103 | strs[i] = seed.substring(0, l);
104 | }
105 | List list = new ArrayList();
106 | for (int c = 10000, i = 0; c > 0; i++, c--) {
107 | list.add(strs[i % strs.length]);
108 | }
109 | String[] arr = list.toArray(new String[list.size()]);
110 | Introsort.sort(arr);
111 | assertTrue(Tests.isSorted(arr));
112 | }
113 |
114 | @Test
115 | public void testRandom() {
116 | List data = Tests.generateData(10000, 100);
117 | String[] arr = data.toArray(new String[data.size()]);
118 | Introsort.sort(arr);
119 | assertTrue(Tests.isSorted(arr));
120 | }
121 |
122 | @Test
123 | public void testHamlet() {
124 | try {
125 | List data = Tests.loadData("hamletwords");
126 | Collections.shuffle(data);
127 | String[] arr = data.toArray(new String[data.size()]);
128 | Introsort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | } catch (IOException ioe) {
131 | fail(ioe.toString());
132 | }
133 | }
134 |
135 | @Test
136 | public void testDictCalls() {
137 | try {
138 | List data = Tests.loadData("dictcalls.gz", true);
139 | String[] arr = data.toArray(new String[data.size()]);
140 | Introsort.sort(arr);
141 | assertTrue(Tests.isSorted(arr));
142 | } catch (IOException ioe) {
143 | fail(ioe.toString());
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/QuicksortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the Quicksort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class QuicksortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | Quicksort.sort((String[]) null);
26 | Quicksort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | Quicksort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | Quicksort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | Quicksort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | Quicksort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | Quicksort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testDictWords() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | String[] arr = data.toArray(new String[data.size()]);
53 | Quicksort.sort(arr);
54 | assertTrue(Tests.isSorted(arr));
55 | } catch (IOException ioe) {
56 | fail(ioe.toString());
57 | }
58 | }
59 |
60 | @Test
61 | public void testSorted() {
62 | try {
63 | List data = Tests.loadData();
64 | Collections.sort(data);
65 | String[] arr = data.toArray(new String[data.size()]);
66 | Quicksort.sort(arr);
67 | assertTrue(Tests.isSorted(arr));
68 | } catch (IOException ioe) {
69 | fail(ioe.toString());
70 | }
71 | }
72 |
73 | @Test
74 | public void testReversed() {
75 | try {
76 | List data = Tests.loadData();
77 | Collections.sort(data);
78 | Collections.reverse(data);
79 | String[] arr = data.toArray(new String[data.size()]);
80 | Quicksort.sort(arr);
81 | assertTrue(Tests.isSorted(arr));
82 | } catch (IOException ioe) {
83 | fail(ioe.toString());
84 | }
85 | }
86 |
87 | @Test
88 | public void testRepeated() {
89 | String[] arr = new String[10000];
90 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
91 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
92 | Arrays.fill(arr, STR);
93 | Quicksort.sort(arr);
94 | assertTrue(Tests.isRepeated(arr, STR));
95 | }
96 |
97 | @Test
98 | public void testRepeatedCycle() {
99 | String[] strs = new String[100];
100 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
101 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
102 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
103 | strs[i] = seed.substring(0, l);
104 | }
105 | List list = new ArrayList();
106 | for (int c = 10000, i = 0; c > 0; i++, c--) {
107 | list.add(strs[i % strs.length]);
108 | }
109 | String[] arr = list.toArray(new String[list.size()]);
110 | Quicksort.sort(arr);
111 | assertTrue(Tests.isSorted(arr));
112 | }
113 |
114 | @Test
115 | public void testRandom() {
116 | List data = Tests.generateData(10000, 100);
117 | String[] arr = data.toArray(new String[data.size()]);
118 | Quicksort.sort(arr);
119 | assertTrue(Tests.isSorted(arr));
120 | }
121 |
122 | @Test
123 | public void testHamlet() {
124 | try {
125 | List data = Tests.loadData("hamletwords");
126 | Collections.shuffle(data);
127 | String[] arr = data.toArray(new String[data.size()]);
128 | Quicksort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | } catch (IOException ioe) {
131 | fail(ioe.toString());
132 | }
133 | }
134 |
135 | @Test
136 | public void testDictCalls() {
137 | try {
138 | List data = Tests.loadData("dictcalls.gz", true);
139 | String[] arr = data.toArray(new String[data.size()]);
140 | Quicksort.sort(arr);
141 | assertTrue(Tests.isSorted(arr));
142 | } catch (IOException ioe) {
143 | fail(ioe.toString());
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/HybridCombsortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the HybridCombsort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class HybridCombsortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | HybridCombsort.sort((String[]) null);
26 | HybridCombsort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | HybridCombsort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | HybridCombsort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | HybridCombsort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | HybridCombsort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | HybridCombsort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testDictWords() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | String[] arr = data.toArray(new String[data.size()]);
53 | HybridCombsort.sort(arr);
54 | assertTrue(Tests.isSorted(arr));
55 | } catch (IOException ioe) {
56 | fail(ioe.toString());
57 | }
58 | }
59 |
60 | @Test
61 | public void testSorted() {
62 | try {
63 | List data = Tests.loadData();
64 | Collections.sort(data);
65 | String[] arr = data.toArray(new String[data.size()]);
66 | HybridCombsort.sort(arr);
67 | assertTrue(Tests.isSorted(arr));
68 | } catch (IOException ioe) {
69 | fail(ioe.toString());
70 | }
71 | }
72 |
73 | @Test
74 | public void testReversed() {
75 | try {
76 | List data = Tests.loadData();
77 | Collections.sort(data);
78 | Collections.reverse(data);
79 | String[] arr = data.toArray(new String[data.size()]);
80 | HybridCombsort.sort(arr);
81 | assertTrue(Tests.isSorted(arr));
82 | } catch (IOException ioe) {
83 | fail(ioe.toString());
84 | }
85 | }
86 |
87 | @Test
88 | public void testRepeated() {
89 | String[] arr = new String[10000];
90 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
91 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
92 | Arrays.fill(arr, STR);
93 | HybridCombsort.sort(arr);
94 | assertTrue(Tests.isRepeated(arr, STR));
95 | }
96 |
97 | @Test
98 | public void testRepeatedCycle() {
99 | String[] strs = new String[100];
100 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
101 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
102 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
103 | strs[i] = seed.substring(0, l);
104 | }
105 | List list = new ArrayList();
106 | for (int c = 10000, i = 0; c > 0; i++, c--) {
107 | list.add(strs[i % strs.length]);
108 | }
109 | String[] arr = list.toArray(new String[list.size()]);
110 | HybridCombsort.sort(arr);
111 | assertTrue(Tests.isSorted(arr));
112 | }
113 |
114 | @Test
115 | public void testRandom() {
116 | List data = Tests.generateData(10000, 100);
117 | String[] arr = data.toArray(new String[data.size()]);
118 | HybridCombsort.sort(arr);
119 | assertTrue(Tests.isSorted(arr));
120 | }
121 |
122 | @Test
123 | public void testHamlet() {
124 | try {
125 | List data = Tests.loadData("hamletwords");
126 | Collections.shuffle(data);
127 | String[] arr = data.toArray(new String[data.size()]);
128 | HybridCombsort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | } catch (IOException ioe) {
131 | fail(ioe.toString());
132 | }
133 | }
134 |
135 | @Test
136 | public void testDictCalls() {
137 | try {
138 | List data = Tests.loadData("dictcalls.gz", true);
139 | String[] arr = data.toArray(new String[data.size()]);
140 | HybridCombsort.sort(arr);
141 | assertTrue(Tests.isSorted(arr));
142 | } catch (IOException ioe) {
143 | fail(ioe.toString());
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/MultikeyQuicksortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit test for the MultikeyQuicksort implementation.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class MultikeyQuicksortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | MultikeyQuicksort.sort((String[]) null);
26 | MultikeyQuicksort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | MultikeyQuicksort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | MultikeyQuicksort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | MultikeyQuicksort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | MultikeyQuicksort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | MultikeyQuicksort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testDictWords() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | String[] arr = data.toArray(new String[data.size()]);
53 | MultikeyQuicksort.sort(arr);
54 | assertTrue(Tests.isSorted(arr));
55 | } catch (IOException ioe) {
56 | fail(ioe.toString());
57 | }
58 | }
59 |
60 | @Test
61 | public void testSorted() {
62 | try {
63 | List data = Tests.loadData();
64 | Collections.sort(data);
65 | String[] arr = data.toArray(new String[data.size()]);
66 | MultikeyQuicksort.sort(arr);
67 | assertTrue(Tests.isSorted(arr));
68 | } catch (IOException ioe) {
69 | fail(ioe.toString());
70 | }
71 | }
72 |
73 | @Test
74 | public void testReversed() {
75 | try {
76 | List data = Tests.loadData();
77 | Collections.sort(data);
78 | Collections.reverse(data);
79 | String[] arr = data.toArray(new String[data.size()]);
80 | MultikeyQuicksort.sort(arr);
81 | assertTrue(Tests.isSorted(arr));
82 | } catch (IOException ioe) {
83 | fail(ioe.toString());
84 | }
85 | }
86 |
87 | @Test
88 | public void testRepeated() {
89 | String[] arr = new String[10000];
90 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
91 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
92 | Arrays.fill(arr, STR);
93 | MultikeyQuicksort.sort(arr);
94 | assertTrue(Tests.isRepeated(arr, STR));
95 | }
96 |
97 | @Test
98 | public void testRepeatedCycle() {
99 | String[] strs = new String[100];
100 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
101 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
102 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
103 | strs[i] = seed.substring(0, l);
104 | }
105 | List list = new ArrayList();
106 | for (int c = 10000, i = 0; c > 0; i++, c--) {
107 | list.add(strs[i % strs.length]);
108 | }
109 | String[] arr = list.toArray(new String[list.size()]);
110 | MultikeyQuicksort.sort(arr);
111 | assertTrue(Tests.isSorted(arr));
112 | }
113 |
114 | @Test
115 | public void testRandom() {
116 | List data = Tests.generateData(10000, 100);
117 | String[] arr = data.toArray(new String[data.size()]);
118 | MultikeyQuicksort.sort(arr);
119 | assertTrue(Tests.isSorted(arr));
120 | }
121 |
122 | @Test
123 | public void testHamlet() {
124 | try {
125 | List data = Tests.loadData("hamletwords");
126 | Collections.shuffle(data);
127 | String[] arr = data.toArray(new String[data.size()]);
128 | MultikeyQuicksort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | } catch (IOException ioe) {
131 | fail(ioe.toString());
132 | }
133 | }
134 |
135 | @Test
136 | public void testDictCalls() {
137 | try {
138 | List data = Tests.loadData("dictcalls.gz", true);
139 | String[] arr = data.toArray(new String[data.size()]);
140 | MultikeyQuicksort.sort(arr);
141 | assertTrue(Tests.isSorted(arr));
142 | } catch (IOException ioe) {
143 | fail(ioe.toString());
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/DualPivotQuicksortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the DualPivotQuicksort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class DualPivotQuicksortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | DualPivotQuicksort.sort((String[]) null);
26 | DualPivotQuicksort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | DualPivotQuicksort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | DualPivotQuicksort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | DualPivotQuicksort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | DualPivotQuicksort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | DualPivotQuicksort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testDictWords() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | String[] arr = data.toArray(new String[data.size()]);
53 | DualPivotQuicksort.sort(arr);
54 | assertTrue(Tests.isSorted(arr));
55 | } catch (IOException ioe) {
56 | fail(ioe.toString());
57 | }
58 | }
59 |
60 | @Test
61 | public void testSorted() {
62 | try {
63 | List data = Tests.loadData();
64 | Collections.sort(data);
65 | String[] arr = data.toArray(new String[data.size()]);
66 | DualPivotQuicksort.sort(arr);
67 | assertTrue(Tests.isSorted(arr));
68 | } catch (IOException ioe) {
69 | fail(ioe.toString());
70 | }
71 | }
72 |
73 | @Test
74 | public void testReversed() {
75 | try {
76 | List data = Tests.loadData();
77 | Collections.sort(data);
78 | Collections.reverse(data);
79 | String[] arr = data.toArray(new String[data.size()]);
80 | DualPivotQuicksort.sort(arr);
81 | assertTrue(Tests.isSorted(arr));
82 | } catch (IOException ioe) {
83 | fail(ioe.toString());
84 | }
85 | }
86 |
87 | @Test
88 | public void testRepeated() {
89 | String[] arr = new String[10000];
90 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
91 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
92 | Arrays.fill(arr, STR);
93 | DualPivotQuicksort.sort(arr);
94 | assertTrue(Tests.isRepeated(arr, STR));
95 | }
96 |
97 | @Test
98 | public void testRepeatedCycle() {
99 | String[] strs = new String[100];
100 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
101 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
102 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
103 | strs[i] = seed.substring(0, l);
104 | }
105 | List list = new ArrayList();
106 | for (int c = 10000, i = 0; c > 0; i++, c--) {
107 | list.add(strs[i % strs.length]);
108 | }
109 | String[] arr = list.toArray(new String[list.size()]);
110 | DualPivotQuicksort.sort(arr);
111 | assertTrue(Tests.isSorted(arr));
112 | }
113 |
114 | @Test
115 | public void testRandom() {
116 | List data = Tests.generateData(10000, 100);
117 | String[] arr = data.toArray(new String[data.size()]);
118 | DualPivotQuicksort.sort(arr);
119 | assertTrue(Tests.isSorted(arr));
120 | }
121 |
122 | @Test
123 | public void testHamlet() {
124 | try {
125 | List data = Tests.loadData("hamletwords");
126 | Collections.shuffle(data);
127 | String[] arr = data.toArray(new String[data.size()]);
128 | DualPivotQuicksort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | } catch (IOException ioe) {
131 | fail(ioe.toString());
132 | }
133 | }
134 |
135 | @Test
136 | public void testDictCalls() {
137 | try {
138 | List data = Tests.loadData("dictcalls.gz", true);
139 | String[] arr = data.toArray(new String[data.size()]);
140 | DualPivotQuicksort.sort(arr);
141 | assertTrue(Tests.isSorted(arr));
142 | } catch (IOException ioe) {
143 | fail(ioe.toString());
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/GnomesortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the Gnomesort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class GnomesortTest {
22 |
23 | /** Maximum number of lines to test for any given file, which avoids
24 | * spending far too much time testing insertion sort on data sets
25 | * that it will never actually be called upon to sort in practice. */
26 | private static final int MAX_LINES = 512;
27 |
28 | @Test
29 | public void testArguments() {
30 | Gnomesort.sort((String[]) null);
31 | Gnomesort.sort(new String[0]);
32 | String[] arr = new String[]{"a"};
33 | Gnomesort.sort(arr);
34 | arr = new String[]{"b", "a"};
35 | Gnomesort.sort(arr);
36 | assertTrue(Tests.isSorted(arr));
37 | arr = new String[]{"c", "b", "a"};
38 | Gnomesort.sort(arr);
39 | assertTrue(Tests.isSorted(arr));
40 | // test with all empty input
41 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
42 | Gnomesort.sort(arr);
43 | for (String s : arr) {
44 | assertEquals("", s);
45 | }
46 | // test with peculiar input
47 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
48 | Gnomesort.sort(arr);
49 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
50 | }
51 |
52 | @Test
53 | public void testDictWords() {
54 | try {
55 | List data = Tests.loadData("dictwords", false, MAX_LINES);
56 | Collections.shuffle(data);
57 | String[] arr = data.toArray(new String[data.size()]);
58 | Gnomesort.sort(arr);
59 | assertTrue(Tests.isSorted(arr));
60 | } catch (IOException ioe) {
61 | fail(ioe.toString());
62 | }
63 | }
64 |
65 | @Test
66 | public void testSorted() {
67 | try {
68 | List data = Tests.loadData("dictwords", false, MAX_LINES);
69 | Collections.sort(data);
70 | String[] arr = data.toArray(new String[data.size()]);
71 | Gnomesort.sort(arr);
72 | assertTrue(Tests.isSorted(arr));
73 | } catch (IOException ioe) {
74 | fail(ioe.toString());
75 | }
76 | }
77 |
78 | @Test
79 | public void testReversed() {
80 | try {
81 | List data = Tests.loadData("dictwords", false, MAX_LINES);
82 | Collections.sort(data);
83 | Collections.reverse(data);
84 | String[] arr = data.toArray(new String[data.size()]);
85 | Gnomesort.sort(arr);
86 | assertTrue(Tests.isSorted(arr));
87 | } catch (IOException ioe) {
88 | fail(ioe.toString());
89 | }
90 | }
91 |
92 | @Test
93 | public void testRepeated() {
94 | String[] arr = new String[MAX_LINES];
95 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
96 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
97 | Arrays.fill(arr, STR);
98 | Gnomesort.sort(arr);
99 | assertTrue(Tests.isRepeated(arr, STR));
100 | }
101 |
102 | @Test
103 | public void testRepeatedCycle() {
104 | String[] strs = new String[100];
105 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
106 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
107 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
108 | strs[i] = seed.substring(0, l);
109 | }
110 | List list = new ArrayList();
111 | for (int c = MAX_LINES, i = 0; c > 0; i++, c--) {
112 | list.add(strs[i % strs.length]);
113 | }
114 | String[] arr = list.toArray(new String[list.size()]);
115 | Gnomesort.sort(arr);
116 | assertTrue(Tests.isSorted(arr));
117 | }
118 |
119 | @Test
120 | public void testRandom() {
121 | List data = Tests.generateData(MAX_LINES, 100);
122 | String[] arr = data.toArray(new String[data.size()]);
123 | Gnomesort.sort(arr);
124 | assertTrue(Tests.isSorted(arr));
125 | }
126 |
127 | @Test
128 | public void testHamlet() {
129 | try {
130 | List data = Tests.loadData("hamletwords", false, MAX_LINES);
131 | Collections.shuffle(data);
132 | String[] arr = data.toArray(new String[data.size()]);
133 | Gnomesort.sort(arr);
134 | assertTrue(Tests.isSorted(arr));
135 | } catch (IOException ioe) {
136 | fail(ioe.toString());
137 | }
138 | }
139 |
140 | @Test
141 | public void testDictCalls() {
142 | try {
143 | List data = Tests.loadData("dictcalls.gz", true, MAX_LINES);
144 | String[] arr = data.toArray(new String[data.size()]);
145 | Gnomesort.sort(arr);
146 | assertTrue(Tests.isSorted(arr));
147 | } catch (IOException ioe) {
148 | fail(ioe.toString());
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/SelectionsortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.util.ArrayList;
9 | import java.io.IOException;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Test the SelectionSort implementations.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class SelectionsortTest {
22 |
23 | /** Maximum number of lines to test for any given file, which avoids
24 | * spending far too much time testing selection sort on data sets
25 | * that it will never actually be called upon to sort in practice. */
26 | private static final int MAX_LINES = 512;
27 |
28 | @Test
29 | public void testArguments() {
30 | Selectionsort.sort((String[]) null);
31 | Selectionsort.sort(new String[0]);
32 | String[] arr = new String[]{"a"};
33 | Selectionsort.sort(arr);
34 | arr = new String[]{"b", "a"};
35 | Selectionsort.sort(arr);
36 | assertTrue(Tests.isSorted(arr));
37 | arr = new String[]{"c", "b", "a"};
38 | Selectionsort.sort(arr);
39 | assertTrue(Tests.isSorted(arr));
40 | // test with all empty input
41 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
42 | Selectionsort.sort(arr);
43 | for (String s : arr) {
44 | assertEquals("", s);
45 | }
46 | // test with peculiar input
47 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
48 | Selectionsort.sort(arr);
49 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
50 | }
51 |
52 | @Test
53 | public void testDictWords() {
54 | try {
55 | List data = Tests.loadData("dictwords", false, MAX_LINES);
56 | Collections.shuffle(data);
57 | String[] arr = data.toArray(new String[data.size()]);
58 | Selectionsort.sort(arr);
59 | assertTrue(Tests.isSorted(arr));
60 | } catch (IOException ioe) {
61 | fail(ioe.toString());
62 | }
63 | }
64 |
65 | @Test
66 | public void testSorted() {
67 | try {
68 | List data = Tests.loadData("dictwords", false, MAX_LINES);
69 | Collections.sort(data);
70 | String[] arr = data.toArray(new String[data.size()]);
71 | Selectionsort.sort(arr);
72 | assertTrue(Tests.isSorted(arr));
73 | } catch (IOException ioe) {
74 | fail(ioe.toString());
75 | }
76 | }
77 |
78 | @Test
79 | public void testReversed() {
80 | try {
81 | List data = Tests.loadData("dictwords", false, MAX_LINES);
82 | Collections.sort(data);
83 | Collections.reverse(data);
84 | String[] arr = data.toArray(new String[data.size()]);
85 | Selectionsort.sort(arr);
86 | assertTrue(Tests.isSorted(arr));
87 | } catch (IOException ioe) {
88 | fail(ioe.toString());
89 | }
90 | }
91 |
92 | @Test
93 | public void testRepeated() {
94 | String[] arr = new String[MAX_LINES];
95 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
96 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
97 | Arrays.fill(arr, STR);
98 | Selectionsort.sort(arr);
99 | assertTrue(Tests.isRepeated(arr, STR));
100 | }
101 |
102 | @Test
103 | public void testRepeatedCycle() {
104 | String[] strs = new String[100];
105 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
106 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
107 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
108 | strs[i] = seed.substring(0, l);
109 | }
110 | List list = new ArrayList();
111 | for (int c = MAX_LINES, i = 0; c > 0; i++, c--) {
112 | list.add(strs[i % strs.length]);
113 | }
114 | String[] arr = list.toArray(new String[list.size()]);
115 | Selectionsort.sort(arr);
116 | assertTrue(Tests.isSorted(arr));
117 | }
118 |
119 | @Test
120 | public void testRandom() {
121 | List data = Tests.generateData(MAX_LINES, 100);
122 | String[] arr = data.toArray(new String[data.size()]);
123 | Selectionsort.sort(arr);
124 | assertTrue(Tests.isSorted(arr));
125 | }
126 |
127 | @Test
128 | public void testHamlet() {
129 | try {
130 | List data = Tests.loadData("hamletwords", false, MAX_LINES);
131 | Collections.shuffle(data);
132 | String[] arr = data.toArray(new String[data.size()]);
133 | Selectionsort.sort(arr);
134 | assertTrue(Tests.isSorted(arr));
135 | } catch (IOException ioe) {
136 | fail(ioe.toString());
137 | }
138 | }
139 |
140 | @Test
141 | public void testDictCalls() {
142 | try {
143 | List data = Tests.loadData("dictcalls.gz", true, MAX_LINES);
144 | String[] arr = data.toArray(new String[data.size()]);
145 | Selectionsort.sort(arr);
146 | assertTrue(Tests.isSorted(arr));
147 | } catch (IOException ioe) {
148 | fail(ioe.toString());
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/Tests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.InputStreamReader;
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.Random;
15 | import java.util.zip.GZIPInputStream;
16 |
17 | /**
18 | * Collection of utility methods to support the unit tests.
19 | *
20 | * @author Nathan Fiedler
21 | */
22 | public class Tests {
23 |
24 | /**
25 | * Creates a new instance of Tests.
26 | */
27 | private Tests() {
28 | }
29 |
30 | /**
31 | * Generates a set of n strings in a List consisting of
32 | * l randomly selected alphanumeric characters (mixed case).
33 | *
34 | * @param n number of random strings to generate.
35 | * @param l length of each random string.
36 | * @return the list of randomly generated strings.
37 | */
38 | public static List generateData(int n, int l) {
39 | Random r = new Random();
40 | List list = new ArrayList();
41 | StringBuilder sb = new StringBuilder();
42 | for (int ii = 0; ii < n; ii++) {
43 | for (int jj = 0; jj < l; jj++) {
44 | int d = r.nextInt(62);
45 | if (d < 10) {
46 | sb.append((char) ('0' + d));
47 | } else if (d < 36) {
48 | sb.append((char) ('A' + (d - 10)));
49 | } else {
50 | sb.append((char) ('a' + (d - 36)));
51 | }
52 | }
53 | list.add(sb.toString());
54 | sb.setLength(0);
55 | }
56 | return list;
57 | }
58 |
59 | /**
60 | * Loads the default test data into a list.
61 | *
62 | * @return test data as a list.
63 | * @throws java.io.IOException
64 | * if a problem occurs.
65 | */
66 | public static List loadData() throws IOException {
67 | // Note that this dictwords file has different content than the
68 | // compressed version, which is much larger.
69 | return loadData("dictwords", false);
70 | }
71 |
72 | /**
73 | * Loads the specified test data into a list of strings.
74 | *
75 | * @param file name of file to be loaded (must be present in classpath).
76 | * @return test data as a list.
77 | * @throws java.io.IOException
78 | * if a problem occurs.
79 | */
80 | public static List loadData(String file) throws IOException {
81 | return loadData(file, false);
82 | }
83 |
84 | /**
85 | * Loads the specified test data into a list of strings.
86 | *
87 | * @param file name of file to be loaded (must be present in classpath).
88 | * @param gzip if true, stream will be decompressed using gzip.
89 | * @return test data as a list.
90 | * @throws java.io.IOException
91 | * if a problem occurs.
92 | */
93 | public static List loadData(String file, boolean gzip) throws IOException {
94 | return loadData(file, gzip, Integer.MAX_VALUE);
95 | }
96 |
97 | /**
98 | * Loads the specified test data into a list of strings.
99 | *
100 | * @param file name of file to be loaded (must be present in classpath).
101 | * @param gzip if true, stream will be decompressed using gzip.
102 | * @param count number of lines to be read.
103 | * @return test data as a list.
104 | * @throws java.io.IOException
105 | * if a problem occurs.
106 | */
107 | public static List loadData(String file, boolean gzip, int count) throws IOException {
108 | InputStream is = Tests.class.getResourceAsStream(file);
109 | if (gzip) {
110 | is = new GZIPInputStream(is);
111 | }
112 | List list = new ArrayList();
113 | InputStreamReader isr = new InputStreamReader(is);
114 | BufferedReader br = new BufferedReader(isr);
115 | for (String ln = br.readLine(); ln != null; ln = br.readLine()) {
116 | list.add(ln);
117 | count--;
118 | if (count == 0) {
119 | break;
120 | }
121 | }
122 | br.close();
123 | return list;
124 | }
125 |
126 | /**
127 | * Tests if the given array of strings is a repeating sequence.
128 | *
129 | * @param arr array of strings to test.
130 | * @param s the expected repeated value.
131 | * @return true if repeating, false otherwise.
132 | */
133 | public static boolean isRepeated(String[] arr, String s) {
134 | for (int ii = 0; ii < arr.length; ii++) {
135 | if (!arr[ii].equals(s)) {
136 | System.err.format("%s != %s @ %d\n", arr[ii], s, ii);
137 | return false;
138 | }
139 | }
140 | return true;
141 | }
142 |
143 | /**
144 | * Tests if the given array of strings is in sorted order.
145 | *
146 | * @param arr array of strings to test.
147 | * @return true if sorted, false otherwise.
148 | */
149 | public static boolean isSorted(String[] arr) {
150 | for (int ii = 1; ii < arr.length; ii++) {
151 | if (arr[ii - 1].compareTo(arr[ii]) > 0) {
152 | System.err.format("%s > %s @ %d\n", arr[ii - 1], arr[ii], ii);
153 | return false;
154 | }
155 | }
156 | return true;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/ShellsortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the Shellsort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class ShellsortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | Shellsort.sort((String[]) null);
26 | Shellsort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | Shellsort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | Shellsort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | Shellsort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | Shellsort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | Shellsort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testSmallSize() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | data = data.subList(0, 10);
53 | String[] arr = data.toArray(new String[data.size()]);
54 | Shellsort.sort(arr);
55 | assertTrue(Tests.isSorted(arr));
56 | } catch (IOException ioe) {
57 | fail(ioe.toString());
58 | }
59 | List data = Tests.generateData(10, 100);
60 | String[] arr = data.toArray(new String[data.size()]);
61 | Shellsort.sort(arr);
62 | assertTrue(Tests.isSorted(arr));
63 | }
64 |
65 | @Test
66 | public void testDictWords() {
67 | try {
68 | List data = Tests.loadData();
69 | Collections.shuffle(data);
70 | String[] arr = data.toArray(new String[data.size()]);
71 | Shellsort.sort(arr);
72 | assertTrue(Tests.isSorted(arr));
73 | } catch (IOException ioe) {
74 | fail(ioe.toString());
75 | }
76 | }
77 |
78 | @Test
79 | public void testSorted() {
80 | try {
81 | List data = Tests.loadData();
82 | Collections.sort(data);
83 | String[] arr = data.toArray(new String[data.size()]);
84 | Shellsort.sort(arr);
85 | assertTrue(Tests.isSorted(arr));
86 | } catch (IOException ioe) {
87 | fail(ioe.toString());
88 | }
89 | }
90 |
91 | @Test
92 | public void testReversed() {
93 | try {
94 | List data = Tests.loadData();
95 | Collections.sort(data);
96 | Collections.reverse(data);
97 | String[] arr = data.toArray(new String[data.size()]);
98 | Shellsort.sort(arr);
99 | assertTrue(Tests.isSorted(arr));
100 | } catch (IOException ioe) {
101 | fail(ioe.toString());
102 | }
103 | }
104 |
105 | @Test
106 | public void testRepeated() {
107 | String[] arr = new String[10000];
108 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
109 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
110 | Arrays.fill(arr, STR);
111 | Shellsort.sort(arr);
112 | assertTrue(Tests.isRepeated(arr, STR));
113 | }
114 |
115 | @Test
116 | public void testRepeatedCycle() {
117 | String[] strs = new String[100];
118 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
119 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
120 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
121 | strs[i] = seed.substring(0, l);
122 | }
123 | List list = new ArrayList();
124 | for (int c = 10000, i = 0; c > 0; i++, c--) {
125 | list.add(strs[i % strs.length]);
126 | }
127 | String[] arr = list.toArray(new String[list.size()]);
128 | Shellsort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | }
131 |
132 | @Test
133 | public void testRandom() {
134 | List data = Tests.generateData(10000, 100);
135 | String[] arr = data.toArray(new String[data.size()]);
136 | Shellsort.sort(arr);
137 | assertTrue(Tests.isSorted(arr));
138 | }
139 |
140 | @Test
141 | public void testHamlet() {
142 | try {
143 | List data = Tests.loadData("hamletwords");
144 | Collections.shuffle(data);
145 | String[] arr = data.toArray(new String[data.size()]);
146 | Shellsort.sort(arr);
147 | assertTrue(Tests.isSorted(arr));
148 | } catch (IOException ioe) {
149 | fail(ioe.toString());
150 | }
151 | }
152 |
153 | @Test
154 | public void testDictCalls() {
155 | try {
156 | List data = Tests.loadData("dictcalls.gz", true);
157 | String[] arr = data.toArray(new String[data.size()]);
158 | Shellsort.sort(arr);
159 | assertTrue(Tests.isSorted(arr));
160 | } catch (IOException ioe) {
161 | fail(ioe.toString());
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/test/org/burstsort4j/HeapsortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009-2011 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.IOException;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import org.junit.Test;
14 | import static org.junit.Assert.*;
15 |
16 | /**
17 | * Unit tests for the Heapsort class.
18 | *
19 | * @author Nathan Fiedler
20 | */
21 | public class HeapsortTest {
22 |
23 | @Test
24 | public void testArguments() {
25 | Heapsort.sort((String[]) null);
26 | Heapsort.sort(new String[0]);
27 | String[] arr = new String[]{"a"};
28 | Heapsort.sort(arr);
29 | arr = new String[]{"b", "a"};
30 | Heapsort.sort(arr);
31 | assertTrue(Tests.isSorted(arr));
32 | arr = new String[]{"c", "b", "a"};
33 | Heapsort.sort(arr);
34 | assertTrue(Tests.isSorted(arr));
35 | // test with all empty input
36 | arr = new String[]{"", "", "", "", "", "", "", "", "", ""};
37 | Heapsort.sort(arr);
38 | for (String s : arr) {
39 | assertEquals("", s);
40 | }
41 | // test with peculiar input
42 | arr = new String[]{"z", "m", "", "a", "d", "tt", "tt", "tt", "foo", "bar"};
43 | Heapsort.sort(arr);
44 | assertTrue("peculiar input not sorted", Tests.isSorted(arr));
45 | }
46 |
47 | @Test
48 | public void testSmallSize() {
49 | try {
50 | List data = Tests.loadData();
51 | Collections.shuffle(data);
52 | data = data.subList(0, 10);
53 | String[] arr = data.toArray(new String[data.size()]);
54 | Heapsort.sort(arr);
55 | assertTrue(Tests.isSorted(arr));
56 | } catch (IOException ioe) {
57 | fail(ioe.toString());
58 | }
59 | List data = Tests.generateData(10, 100);
60 | String[] arr = data.toArray(new String[data.size()]);
61 | Heapsort.sort(arr);
62 | assertTrue(Tests.isSorted(arr));
63 | }
64 |
65 | @Test
66 | public void testDictWords() {
67 | try {
68 | List data = Tests.loadData();
69 | Collections.shuffle(data);
70 | String[] arr = data.toArray(new String[data.size()]);
71 | Heapsort.sort(arr);
72 | assertTrue(Tests.isSorted(arr));
73 | } catch (IOException ioe) {
74 | fail(ioe.toString());
75 | }
76 | }
77 |
78 | @Test
79 | public void testSorted() {
80 | try {
81 | List data = Tests.loadData();
82 | Collections.sort(data);
83 | String[] arr = data.toArray(new String[data.size()]);
84 | Heapsort.sort(arr);
85 | assertTrue(Tests.isSorted(arr));
86 | } catch (IOException ioe) {
87 | fail(ioe.toString());
88 | }
89 | }
90 |
91 | @Test
92 | public void testReversed() {
93 | try {
94 | List data = Tests.loadData();
95 | Collections.sort(data);
96 | Collections.reverse(data);
97 | String[] arr = data.toArray(new String[data.size()]);
98 | Heapsort.sort(arr);
99 | assertTrue(Tests.isSorted(arr));
100 | } catch (IOException ioe) {
101 | fail(ioe.toString());
102 | }
103 | }
104 |
105 | @Test
106 | public void testRepeated() {
107 | String[] arr = new String[10000];
108 | final String STR = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
109 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
110 | Arrays.fill(arr, STR);
111 | Heapsort.sort(arr);
112 | assertTrue(Tests.isRepeated(arr, STR));
113 | }
114 |
115 | @Test
116 | public void testRepeatedCycle() {
117 | String[] strs = new String[100];
118 | String seed = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
119 | + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
120 | for (int i = 0, l = 1; i < strs.length; i++, l++) {
121 | strs[i] = seed.substring(0, l);
122 | }
123 | List list = new ArrayList();
124 | for (int c = 10000, i = 0; c > 0; i++, c--) {
125 | list.add(strs[i % strs.length]);
126 | }
127 | String[] arr = list.toArray(new String[list.size()]);
128 | Heapsort.sort(arr);
129 | assertTrue(Tests.isSorted(arr));
130 | }
131 |
132 | @Test
133 | public void testRandom() {
134 | List data = Tests.generateData(10000, 100);
135 | String[] arr = data.toArray(new String[data.size()]);
136 | Heapsort.sort(arr);
137 | assertTrue(Tests.isSorted(arr));
138 | }
139 |
140 | @Test
141 | public void testHamlet() {
142 | try {
143 | List data = Tests.loadData("hamletwords");
144 | Collections.shuffle(data);
145 | String[] arr = data.toArray(new String[data.size()]);
146 | Heapsort.sort(arr);
147 | assertTrue(Tests.isSorted(arr));
148 | } catch (IOException ioe) {
149 | fail(ioe.toString());
150 | }
151 | }
152 |
153 | // @Test -- takes much too long to finish
154 | public void testDictCalls() {
155 | try {
156 | List data = Tests.loadData("dictcalls.gz", true);
157 | String[] arr = data.toArray(new String[data.size()]);
158 | Heapsort.sort(arr);
159 | assertTrue(Tests.isSorted(arr));
160 | } catch (IOException ioe) {
161 | fail(ioe.toString());
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/org/burstsort4j/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008-2012 Nathan Fiedler. All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 | package org.burstsort4j;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.BufferedWriter;
10 | import java.io.FileReader;
11 | import java.io.FileWriter;
12 | import java.io.IOException;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | import java.io.InputStreamReader;
17 | import java.io.OutputStreamWriter;
18 | import java.util.zip.GZIPInputStream;
19 | import java.util.zip.GZIPOutputStream;
20 | import java.io.FileInputStream;
21 | import java.io.FileOutputStream;
22 | import java.io.Reader;
23 | import java.io.Writer;
24 |
25 | /**
26 | * Command-line interface to the various sort implementations.
27 | *
28 | * @author Nathan Fiedler
29 | */
30 | public class Main {
31 |
32 | private static final String BURSTSORT = "--burstsort";
33 | private static final String FUNNELSORT = "--funnelsort";
34 | private static final String MULTIKEY = "--multikey";
35 |
36 | private Main() {
37 | }
38 |
39 | /**
40 | * Main entry point for the sorter.
41 | *
42 | * @param args command line arguments.
43 | */
44 | public static void main(String[] args) {
45 | if (args.length < 2 || args.length > 3) {
46 | usage();
47 | }
48 | String input;
49 | String output;
50 | String sort;
51 | if (args.length == 3) {
52 | sort = args[0];
53 | input = args[1];
54 | output = args[2];
55 | } else {
56 | sort = BURSTSORT;
57 | input = args[0];
58 | output = args[1];
59 | }
60 |
61 | // Read in the input file.
62 | long r1 = System.currentTimeMillis();
63 | String[] data = readFile(input);
64 | long r2 = System.currentTimeMillis();
65 | System.out.format("Read time: %dms\n", r2 - r1);
66 |
67 | // Sort the data using the selected sort.
68 | long s1 = System.currentTimeMillis();
69 | if (sort.equals(FUNNELSORT)) {
70 | LazyFunnelsort.sort(data);
71 | } else if (sort.equals(BURSTSORT)) {
72 | Burstsort.sort(data);
73 | } else if (sort.equals(MULTIKEY)) {
74 | MultikeyQuicksort.sort(data);
75 | } else {
76 | usage();
77 | }
78 | long s2 = System.currentTimeMillis();
79 | System.out.format("Sort time: %dms\n", s2 - s1);
80 |
81 | // Write the results to the output file.
82 | long w1 = System.currentTimeMillis();
83 | writeFile(output, data);
84 | long w2 = System.currentTimeMillis();
85 | System.out.format("Write time: %dms\n", w2 - w1);
86 | }
87 |
88 | /**
89 | * Display usage information and exit.
90 | */
91 | private static void usage() {
92 | System.out.println("Usage: Main [options]