基数排序

参考资料:算法导论

性能:给定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 }
posted @ 2014-09-12 22:42  rldts  阅读(625)  评论(0编辑  收藏  举报