三亚兼职招聘信息网站软件开发文档国标
三亚兼职招聘信息网站,软件开发文档国标,免费的行情网站app大全下载,河南省建设银行网站目录
前言
基数排序
算法思想
编辑
算法示例
代码实现
1.队列queue.h 头文件
2.队列queue.c 源文件 3.主函数#xff08;radix_sort实现#xff09;
算法分析 前言 今天我想把前面未更新完的排序算法补充一下#xff0c;也就是基数排序的一种#xff0c;这是跟… 目录
前言
基数排序
算法思想
编辑
算法示例
代码实现
1.队列queue.h 头文件
2.队列queue.c 源文件 3.主函数radix_sort实现
算法分析 前言 今天我想把前面未更新完的排序算法补充一下也就是基数排序的一种这是跟计数排序一样类型的排序算法是属于非比较型的排序算法下面我们就一起来看看吧。
基数排序 基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机 (Tabulation Machine)上的贡献。它是这样实现的将所有待比较数值正整数统一为同样的数位长度数位较短的数前面补零。然后从最低位开始依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。 基数排序的方式可以采用LSDLeast significant digital或MSDMost significant digitalLSD的排序方式由键值的最右边开始而MSD则相反由键值的最左边开始。 算法思想 上面这些理论思想看上去不太好理解那下面我举个例子去简单解释一下。
算法示例
比如有这么一个数组 array {53, 3, 542, 748, 14, 214, 154, 63, 616} 现在要去进行基数排序。
这里我们需要去创建一个长度为10的队列数组。Queue que[10]。然后这个队列数组作为根据基数储存数据的队列表。
这里我们对数组中的每一个数字去进行遍历然后进行按位求余最先是个位数得到的结果根据对应的队列数组下标去进行入队操作。基数分配结果如下所示:
第一次基数分配根据个位数分配 que[0]-----NULL que[1]-----NULL que[2]-----542-----NULL que[3]-----53------3-----63-----NULL que[4]-----14-----214-----154-----NULL que[5]-----NULL que[6]-----616-----NULL que[7]-----NULL que[8]-----748-----NULL que[9]-----NULL 然后根据第一次基数计算出的结果重新去排放这个数组对这个队列表进行遍历从上到下然后出队操作出队的结果放入到数组当中第一次数组更新结果如下 [ 542, 53, 3, 63, 14, 214, 154, 616, 748 ] 第二次基数分配根据十位数分配
在进行第二次分配的时候我们就根据上面已经跟新好了的数组去重新分配这一次我们就要去进一位来分配。结果如下 que[0]-----3-----NULL que[1]-----14-----214-----616-----NULL que[2]-----NULL que[3]-----NULL que[4]-----542-----748-----NULL que[5]-----53-----154-----NULL que[6]-----63-----NULL que[7]-----NULL que[8]-----NULL que[9]-----NULL 根据第二次基数计算出的结果重新去排放这个数组对这个队列表进行遍历从上到下然后出队操作出队的结果放入到数组当中第二次数组更新结果如下 [ 3, 14, 214 ,616, 542, 748, 53, 154, 63 ] 第三次基数分配根据百位数分配
我们接着取上面第二次分配的数组结果然后再次根据百位数求余数分配。结果如下 que[0]-----3-----14-----53-----63-----NULL que[1]-----154-----NULL que[2]-----214-----NULL que[3]-----NULL que[4]-----NULL que[5]-----542-----NULL que[6]-----616-----NULL que[7]-----748-----NULL que[8]-----NULL que[9]-----NULL 根据第三次基数计算出的结果重新去排放这个数组对这个队列表进行遍历从上到下然后出队操作出队的结果放入到数组当中第三次数组更新结果如下 [ 3, 14, 53, 63, 154, 214, 542, 616, 748 ] 这里我们可以看出已经拍好序了但是我建议还是继续去第四次分配直到全部的数字都在队列que[0]上。
第四次基数分配根据千位数分配
同样的这里我们把基数再进一位 que[0]-----3-----14-----53-----63-----154-----214-----542-----616-----748-----NULL que[1]-----NULL que[2]-----NULL que[3]-----NULL que[4]-----NULL que[5]-----NULL que[6]-----NULL que[7]-----NULL que[8]-----NULL que[9]-----NULL 此时的全部数字都在第一个队列上这时候就完成了排序只需要去对这个队列进行出队然后把数据重新放入到数组当中结果如下至此排序结束。 [ 3, 14, 53, 63, 154, 214, 542, 616, 748 ] 整体分配过程 假设r是排序码的基数d是排序码的位数每位的类型是KeyType待排序的文件采用带表头结点的链表表示类型为RadixList口为了便于实现记录的分配和收集建立r个链表表示的队列每个队列的类型为Queue 动态图 代码实现
1.队列queue.h 头文件
#pragma once
#includestdlib.h//数据类型
typedef int Datatype;//节点
typedef struct node {Datatype data;struct node* next;
}Lnode;
//队列
typedef struct queue {int curnum;Lnode* front, * rear;
}Queue;//队列初始化
void queue_init(Queue* que);
//判空
int isEmpty(Queue q);
//入队列
void enqueue(Queue *que, Datatype data);
//出队列
Lnode* dequeue(Queue* que);
//获取队头元素
Datatype get_headdata(Queue que);
2.队列queue.c 源文件
#includequeue.h
#includeassert.h//队列初始化
void queue_init(Queue* que) {que-curnum 0;que-front que-rear NULL;
}//创建一个节点
Lnode* create_node(Datatype data) {Lnode* node (Lnode*)malloc(sizeof(Lnode));assert(node);node-data data;node-next NULL;return node;
}//判空
int isEmpty(Queue q) {return q.curnum 0;
}//入队列
void enqueue(Queue *que,Datatype data) {Lnode* add create_node(data);if (isEmpty(*que)) {que-front que-rear add;que-curnum;}else {que-rear-next add;que-rear add;que-curnum;}
}//出队列
Lnode* dequeue(Queue *que) {if (isEmpty(*que))return NULL;if (que-curnum 1)que-rear NULL;Lnode* de que-front;que-front de-next;que-curnum--;return de;
}//获取队头元素
Datatype get_headdata(Queue que) {return que.front-data;
} 3.主函数radix_sort实现
#includestdio.h
#includestdlib.h
#includequeue.hvoid radix_sort(int* arr, int n) {Queue que[10];//创建下标为0~9的队列for (int i 0; i 10; i) {queue_init(que[i]);//初始化队列}for (int i 0; i n; i) {enqueue(que[arr[i] % 10], arr[i]);//把数组个位数的数字依次入队}int k 0;int count 10;while (que[0].curnum ! n) {//如果数字里面全部的数据到第0个队列的时候就结束for (int i 0; i 10; i) {while (!isEmpty(que[i])) {Lnode* pop dequeue(que[i]);//出队arr[k] pop-data;//重新放置数组//释放空间free(pop);pop NULL;}}k 0;for (int i 0; i n; i) {//除以count取整此时指向进一位数字进行入队操作int x arr[i] / count;enqueue(que[x % 10], arr[i]);}count * 10;//}
}int main() {int array[] { 123,0, 25,24,6,65,11,43,22,51 ,999 };printf(排序前:);for (int i 0; i sizeof(array) / sizeof(int); i) {printf(%d , array[i]);}//基数排序radix_sort(array, sizeof(array) / sizeof(int));printf(\n排序后);for (int i 0; i sizeof(array) / sizeof(int); i) {printf(%d , array[i]);}
}
输出结果 算法分析 基数排序算法中时间主要耗费在修改指针上一趟排序的时间为O(rn)总共要进行d趟排序基数排序的时间复杂度T(n) O(d*(rn))采用链表存储排序时只修改链接指针,操作效率不受记录的信息量大小的影响排序中每个记录中增加了一个next字段(链表指针)还增加了一个queue 数组,故辅助空间S(n) O(nr基数排序是稳定的 以上就是本期的全部内容了我们下次见咯~ 分享一张壁纸
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/90093.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!