基数排序

参考资料:算法导论

性能:给定n个d位数,每一个数位可以取k种可能的值,基数排序算法时间为O(d(n+k)),当d为常数,k=O(n)时,基数排序为O(n)时间

优点:稳定排序

缺点:不是原地排序

实现代码(用户需要提供一个RSHelper的实现即可完成排序,本例给出一个随意的实现仅作示意)

RadixSort.java

 1 package sorts;

 2 

 3 import java.util.ArrayList;

 4 import java.util.HashMap;

 5 import java.util.LinkedList;

 6 import java.util.List;

 7 import java.util.Map;

 8 import java.util.Queue;

 9 import java.util.Set;

10 

11 import test.RSHelper;

12 

13 public class RadixSort {

14     

15     private RadixSort() {

16         

17     }

18     

19     public static <K extends Comparable<K>, T> void sort(RSHelper<K, T> helper) {

20         // initialize

21         Set<K> keys = helper.keys();

22         Map<K, Queue<T>> map = new HashMap<K, Queue<T>>();

23         List<Queue<T>> queues = new ArrayList<Queue<T>>();

24         for (int i = 0; i < keys.size(); i++) {

25             queues.add(new LinkedList<T>());

26         }

27         int i = 0;

28         for (K k : keys) {

29             map.put(k, queues.get(i++));

30         }

31         int dataLength = helper.dataLength();

32         // sort

33         T data = null;

34         K key = null;

35         for (i = 0; i < dataLength; i++) {

36             while (helper.hasNext()) {

37                 data = helper.next();

38                 key = helper.key(data, i);

39                 map.get(key).offer(data);

40             }

41             for (Queue<T> queue : queues) {

42                 while (!queue.isEmpty()) {

43                     data = queue.poll();

44                     helper.put(data);

45                 }

46             }

47         }

48     }

49     

50 }

RSHelper.java

 1 package test;

 2 

 3 import java.util.Set;

 4 

 5 public interface RSHelper<K extends Comparable<K>, T> {

 6     /**

 7      * @return true if there's still data available, false otherwise.

 8      * */

 9     boolean hasNext();

10     /**

11      * @return the next data. 

12      * */

13     T next(); 

14     /**

15      * @param index starts from 0 (the lowest index)

16      * @param data the data where the key is from.

17      * @return the key at the specified index in the data.

18      * */

19     K key(T data, int index);

20     /**

21      * @return the keys that will be involved while sorting. The set must be sorted according

22      * to the natural order of the keys.

23      * */

24     Set<K> keys();

25     

26     /**

27      * @return the number of keys in one data object.

28      * */

29     int dataLength();

30     /**

31      * Put the data back to the client, in a sequential manner

32      * that the client can receive the result of one round of sorting.

33      * */

34     void put(T data);

35 }

TestRadixSort.java

  1 package test;

  2 

  3 import java.util.Arrays;

  4 import java.util.Random;

  5 import java.util.Set;

  6 import java.util.TreeSet;

  7 

  8 import sorts.RadixSort;

  9 

 10 class DataType {

 11     

 12     Integer[] arr = new Integer[3];

 13     public DataType(int a, int b, int c) {

 14         if (a > 9 || b > 9 || c > 9) {

 15             throw new IllegalArgumentException("Argument should be no more than 9.");

 16         }

 17         arr[0] = a;

 18         arr[1] = b;

 19         arr[2] = c;

 20     }

 21     int get(int index) {

 22         return arr[3-index-1];

 23     }

 24     void set(int index, int value) {

 25         arr[3-index-1] = value;

 26     }

 27     static int dataLength() {

 28         return 3;

 29     }

 30     @Override

 31     public String toString() {

 32         return arr[0] + "" + arr[1] + "" + arr[2];

 33     }

 34 }

 35 

 36 class MyRSHelper implements RSHelper<Integer, DataType> {

 37     

 38     static Set<Integer> keySet = new TreeSet<>();

 39     static {

 40         for (int i = 0; i < 10; i++) {

 41             keySet.add(i);

 42         }

 43     }

 44     

 45     int index = 0;

 46     DataType[] arr = new DataType[10];

 47     

 48     public MyRSHelper() {

 49         int bound = 10;

 50         Random random = new Random();

 51         for (int i = 0; i < arr.length; i++) {

 52             arr[i] = new DataType(random.nextInt(bound), 

 53                     random.nextInt(bound), random.nextInt(bound));

 54         }

 55     }

 56 

 57     @Override

 58     public boolean hasNext() {

 59         return (index < arr.length);

 60     }

 61 

 62     @Override

 63     public DataType next() {

 64         DataType result = arr[index];

 65         arr[index] = null;

 66         index++;

 67         return result;

 68     }

 69 

 70     @Override

 71     public Integer key(DataType data, int index) {

 72         return data.get(index);

 73     }

 74 

 75     @Override

 76     public Set<Integer> keys() {

 77         return keySet;

 78     }

 79 

 80     @Override

 81     public int dataLength() {

 82         return DataType.dataLength();

 83     }

 84 

 85     @Override

 86     public void put(DataType data) {

 87         if (index == arr.length) {

 88             index = 0;

 89         }

 90         arr[index++] = data;

 91         if (index == arr.length) {

 92             index = 0;

 93         }

 94     }

 95     

 96     @Override

 97     public String toString() {

 98         return Arrays.toString(arr);

 99     }

100 

101 }

102 

103 public class TestRadixSort {

104     // test

105     public static void main(String[] args) {

106         MyRSHelper helper = new MyRSHelper();

107         RadixSort.sort(helper);

108         System.out.println(helper);

109     }

110 }

你可能感兴趣的:(基数排序)