基数排序
转自 http://blog.csdn.net/pigli/article/details/5755439
基数排序(Radix Sorting):
基数排序是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法。
1. 多关键字排序思想
多关键字排序也就是对一个序列中每项数据都包含有多个关键字的序列进行排序。比如说对一幅扑克牌进行排序,扑克牌就包括花色和面值这两个关键字。有两种排序方法:
第一种方法:按照花色我们将扑克牌分成四堆。然后再对每堆扑克按照面值的大小进行排序。最后,按照花色大小顺序将这四队扑克牌收成一堆。这样扑克牌就排序好了。
第二种方法:首先按照面值我们将扑克牌分成13堆。然后每堆按照花色顺序排列。也就是说,这13堆的最上面一张扑克的花色均为梅花(若小的排在上面,大的排在下面)。接着,我们将这最上面的13张梅花按照面值从小到大收集起来最为最下面的13张扑克,接着收集方块的13张扑克,以此直到收集完毕所以的扑克。这时,扑克的排序也进行完毕。
从上面的排序过程可以总结出多关键字排序的思想:首先按照某一个关键字进行排序,使序列按照一个关键排列有序,然后再在基础上对下一个关键进行排序,使得下一个关键字也有序,如此,只到所有的关键字均有需。
从上面的排序过程还可以看出多关键字的排序实际上包括两个过程:分配和收集。
2. 何为单逻辑关键字
个人理解,但逻辑关键字是指将待排序列中元素拆分成多个关键字。而关键字序列由相同的元素组成。比如说将123这个三位数拆分成由1,2,3这三个关键字组成的多关键字序列。
基数排序,这个基radix就是指的关键字的取值范围,也即是关键字的个数。如:若对十进制数进行排序,经过拆分后,每个关键字都是由0-9之间的数组成,那么基就是为10。
下面描述对十进制数进行基数排序的具体方法:
1. 采用静态链表对待排序的元素进行存储,静态链表中存储的元素包括两个部分:数据域和next域。Next域用来存储,排在此元素之后的数据的位置。
2. 还需要两个int型辅助数组f[radix],e[radix]。在此例中radix==10。
F为头指针,e为尾指针。
3. 排序总体上来说是包括两个过程:分配和收集。下面来描述在一趟排序中的分配和收集的过程:
分配:总体上来说是将数据按照第一个关键字,将数据分配到各自的类别上。Radix代表的是相应的类别,f[radix]中存储的是这个类别的第一个元素的序号,e[radix]存储的是这个类别最后一个元素的序号。F e起到的是 一个指针表示的作用。
收集:总体上来说是将各个类别的数据按照类别大小依次串联起来。
注意一趟收集完毕之后,要将f和e数组进行清空。
具体实现如下:
- package search;
- /*
- * 基数排序的基本原理其实是:使得一个关键字有序的基础上使得另外一个关键字也有序。当所有的关键字均有序的时候,有序的序列表也就出来了。
- * 基数排序要注意每走完一趟要清空指针数组f和e
- */
- public class RadixSort {
- private node[] rlist;
- private int[] f;
- private int[] e;
- private int numOfKey;
- class node{
- int key;
- int next;
- public node(int key,int next)
- {
- this.key = key;
- this.next = next;
- }
- }
- public RadixSort(int[] array,int numOfKey)
- {
- rlist = new node[array.length+1];
- f = new int[10];
- e = new int[10];
- this.numOfKey = numOfKey;
- rlist[0] = new node(0,1);
- for(int i =0;i<array.length;i++)
- {
- if(i==array.length-1)
- {
- rlist[i+1] = new node(array[i],0);
- }
- else
- {
- rlist[i+1] = new node(array[i],i+2);
- }
- }
- for(int i=0;i<10;i++)
- {
- f[i] = 0;
- e[i] = 0;
- }
- }
- public void distribute(int i)
- {
- int p = rlist[0].next;
- while(p!=0)
- {
- int j = map(rlist[p],i);
- if(f[j]==0)
- {
- f[j]=p;
- }
- else
- {
- rlist[e[j]].next = p;
- }
- e[j] =p;
- p = rlist[p].next;
- }
- }
- public void collect()
- {
- int i =0 ;
- int end =0;
- for(;f[i]==0;i++);
- rlist[0].next = f[i];
- end = e[i];
- while(i<10)
- {
- i++;
- if(i<10&&f[i]!=0)
- {
- rlist[end].next = f[i];
- end = e[i];
- }
- }
- rlist[end].next =0;
- }
- public int map(node p,int i)
- {
- int j =0;
- int data = p.key;
- switch(i)
- {
- case 1:
- j = data%10;
- break;
- case 2:
- j = (data/10)%10;
- break;
- case 3:
- j = data/100;
- }
- return j;
- }
- public void sort()
- {
- for(int i=1;i<=numOfKey;i++)
- {
- distribute(i);
- collect();
- clearArray(); //这是需要着重注意的一点!
- }
- }
- public void print()
- {
- for(int i=rlist[0].next;i!=0;i = rlist[i].next)
- {
- System.out.print("key:"+rlist[i].key+" "+"next:"+rlist[i].next);
- System.out.println();
- }
- }
- public void clearArray()
- {
- for(int i=0;i<10;i++)
- {
- f[i] = 0;
- e[i] = 0;
- }
- }
- public static void main(String args[])
- {
- int[] array = {567,678,567,45,46,26,345,378,23,257};
- RadixSort radixSort = new RadixSort(array,3);
- radixSort.sort();
- radixSort.print();
- }
- }
浙公网安备 33010602011771号