分配类排序——基数排序
来源:互联网 发布:魔秀做主题软件图标 编辑:程序博客网 时间:2024/06/10 21:48
基数排序属于“分配式排序”(distribution sort),基数排序法又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序。
时间效率:设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。
最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。
最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。
下面是C语言实现的一个例子(使用最低优先法)
#include <unistd.h>#include <assert.h>#include <stdio.h>#include <stdlib.h>#define RADIX 10 //基数#define KEY_SIZE 6 //键的最大个数#define LIST_SIZE 20 //需要排序数的个数typedef struct{ int key; int next; //静态链域} RecordType1;typedef struct {RecordType1 r[LIST_SIZE + 1];int length;int keynum;} SLinkList; //静态链表typedef int PVector[RADIX];int num[LIST_SIZE][KEY_SIZE]; //将整数进行分离/*将输入的十进制数的每一位拆分开来*/void Order(SLinkList *s_num){int i, m, j, tmp;int r_num; m = s_num->keynum;for (i = 1; i <= s_num->length; i++){ r_num = s_num->r[i].key;for (j = m-1; j >= 0; j--) {tmp = r_num % 10;num[i][j] = tmp;r_num = r_num / 10;while (r_num == 0 && j != 0){j--;num[i][j] = 0;break;}}}}/*分配*/void Distribute(SLinkList *s_num, int i, PVector head, PVector tail){int j, p;for (j = 0; j <= RADIX-1; ++j){head[j] = 0;}p = s_num->r[0].next;while(p != 0){j = num[p][i];if (head[j] == 0) head[j] = p; else s_num->r[tail[j]].next = p;tail[j] = p;p = s_num->r[p].next;}}/*回收*/void Collect(SLinkList *s_num, PVector head, PVector tail){int j, t;j = 0;while (head[j] == 0) ++j;s_num->r[0].next = head[j];t = tail[j];while (j < RADIX - 1){++j;while ((j < RADIX - 1) && (head[j] == 0)){++j;}if (head[j] != 0){s_num->r[t].next = head[j];t = tail[j];}}s_num->r[t].next = 0;}//找最大数int maxNum(SLinkList *s_num){int i, max = 0;for (i = 1; i <= s_num->length; i++){if (s_num->r[i].key > max) max = s_num->r[i].key;}return max;}/*确定关键字的个数(找最大数关键子的位数)*/void Keynum(SLinkList *s_num){int max_num, temp = 0, count = 1;max_num = maxNum(s_num); //找最大数temp = max_num / 10;while (temp != 0){count++;temp = temp / 10;}s_num->keynum = count;}/*基数排序*/void RadixSort(SLinkList *s_num){PVector head, tail;int i, d, n;n = s_num->length;for (i = 0; i <= n-1; ++i) s_num->r[i].next = i+1;s_num->r[n].next = 0;d = s_num->keynum; //关键字的个数for (i = d-1; i >= 0; i--){Distribute(s_num, i, head, tail); //第i趟分配Collect(s_num, head, tail); //第i趟回收}}/*输出排序后的结果*/void Print(SLinkList *s_num){int j;j = s_num->r[0].next;printf("\nsort finish:");while (j != 0){printf("%d ", s_num->r[j].key);j = s_num->r[j].next;}printf("\n");}int main(int argc, char *argv[]){SLinkList *s_num; int i;s_num = (SLinkList *)malloc(sizeof(SLinkList));printf("input sort count is : ");scanf("%d", &s_num->length);printf("\nPlease input sort number is :");for (i = 1; i <= s_num->length; i++){scanf("%d", &s_num->r[i].key);} Keynum(s_num); //计算关键字的个数Order(s_num); //将输入的十进制数进行拆分RadixSort(s_num);Print(s_num);return EXIT_SUCCESS;}
- 分配类排序——基数排序
- 分配排序-基数排序
- 分配排序之--基数排序
- 排序——基数排序
- 排序——基数排序
- 排序——基数排序
- 内部排序—基数排序
- 8.5内部排序法---分配类排序(基数排序)
- 排序——基数排序 收藏
- 排序算法——基数排序
- 排序算法——基数排序
- 排序算法——基数排序
- 排序算法——基数排序
- 分配排序之--桶排序,基数排序
- 排序—基数排序(js实现)
- 非比较排序—计数排序&基数排序
- (四)分配排序:基数排序(radix sort)
- 图解"数据结构--内部排序算法"----分配排序:箱排序、基数排序
- (译)如何使用cocos2d来做一个简单的iphone游戏教程(第一部分)
- netfilter
- 专利法上的抽象思想与具体技术 ——计算机程序算法的客体属性分析
- 密码学基础概念
- MYSQL集群部署(三)--集群部署
- 分配类排序——基数排序
- MediaStore.Audio.Media字段的含义
- 支持中文文本的数据挖掘平台开源项目PyMining发布
- hdu 4679 Terrorist’s destroy ( 树形dp 树的直径 )
- 初识ant
- staticInter
- HDU 4548 -------美素数
- MySQL的安装与基本命令
- netfilter