基数排序
来源:互联网 发布:淘宝家具配送安装接单 编辑:程序博客网 时间:2024/06/15 23:50
基数排序(Radix Sorting) 又称为桶排序或数字排序:按待排序记录的关键字的组成成分(或“位”)进行排序。
排序思想
⑴ 首先以静态链表存储n个待排序记录,头结点指针指向第一个记录结点;
⑵ 一趟排序的过程是:
① 分配: 按Kd值的升序顺序,改变记录指针,将链表中的记录结点分配到r个链表(桶)中,每个链表中所有记录的关键字的最低位(Kd)的值都相等,用f[i]、e[i]作为第i个链表的头结点和尾结点;
② 收集:改变所有非空链表的尾结点指针,使其指向下一个非空连表的第一个结点,从而将r个链表中的记录重新链接成一个链表;
⑶ 如此依次按分别进行,共进行d趟排序后排序完成。
排序示例
设有关键字序列为1039, 2121, 3355, 4382, 66, 118的一组记录,采用链式基数排序的过程如下图所示。
算法实现
为实现基数排序,用两个指针数组来分别管理所有的缓存(桶),同时对待排序记录的数据类型进行改造,相应的数据类型定义如下:
#define BIT_key 8 /* 指定关键字的位数d */#define RADIX 10 /* 指定关键字基数r */typedef struct RecType{ char key[BIT_key]; /* 关键字域 */ infoType otheritems; struct RecType *next;}SRecord, *f[RADIX] ,*e[RADIX];/* 桶的头尾指针数组 */void Radix_sort(SRecord *head ){ int j, k, m ; SRecord *p, *q, *f[RADIX], *e[RADIX]; for (j=BIT_key-1; j>=0; j--) /* 关键字的每位一趟排序 */ { for (k=0; k<RADIX; k++) f[k]=e[k]=NULL; /* 头尾指针数组初始化 */ p=head ; while (p!=NULL) /* 一趟基数排序的分配 */ { m=ord(p->key[j]); /* 取关键字的第j位kj */ if(f[m]==NULL) f[m]=p; else e[m]->next=p; p=p->next; } head=NULL; /* 以head作为头指针进行收集 */ q=head; /* q作为收集后的尾指针 */ for (k=0; k<RADIX; k++) { if(f[k]!=NULL) /* 第k个队列不空则收集 */ { if(head!=NULL) q->next=f[k]; else head=f[k]; q=e[k]; } } /* 完成一趟排序的收集 */ q->next=NULL; /* 修改收集链尾指针 */ }}
算法分析
设有n个待排序记录,关键字位数为d,每位有r种取值。则排序的趟数是d;在每一趟中:
◆ 链表初始化的时间复杂度:O(r) ;
◆ 分配的时间复杂度:O(n) ;
◆ 分配后收集的时间复杂度:O(r) ;
则链式基数排序的时间复杂度为: O(d(n+r))
在排序过程中使用的辅助空间是:2r个链表指针, n个指针域空间,则空间复杂度为:O(n+r)
基数排序是稳定的。
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- GPG加密和签名
- Help of the linux commands
- Linux Wireless基础知识
- jQuery源码分析-10事件处理-Event-DOM-ready
- XMLHTTPRequest
- 基数排序
- Linux命令总结
- 如何判断两个矩形相交
- 3.3.4.5. 日期计算
- ajax提交加载进度条示例代码
- jQuery源码分析-10事件处理-Event-事件绑定与删除-bind/unbind+live/die+delegat/unde
- Cacti显示端口名称不全的问题
- Linux下常用解压命令
- 3.3.4.6. NULL值操作