转载http://blog.csdn.net/Shayabean_/article/details/44885917博客

先说说基数排序的思想

基数排序是非比较型的排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。

将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。在每一次排序中,按照当前位把数组元素放到对应

的桶当中,然后把桶0到桶9中的元素按先进先出的方式放回数组中。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

这个版本的基数排序RadixSort(L,max)较RadixSort(L)不同的是需要输入待排序列最大数的位数。因为RadixSort(L)最大数位在程序中已经计算过了,因为需要计算最大数,所以需要对待排链表最开始循环一次,所以RadixSort(L,max)速度比RadixSort(L)稍快。

这篇博客包括4个文件,两个头文件RadixSort.h和fatal.h,一个库函数RadixSort.c,和一个测试文件Test_Radix_Sort.c

头文件fatal.h:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define Error(Str) FatalError(Str)
  4. #define FatalError(Str) fprintf(stderr, "%s\n", Str), exit(1);

头文件RadixSort.h

  1. typedef int ElementType;
  2. #ifndef RADIX_SORT_H
  3. #define RADIX_SORT_H
  4.  
  5. #include<stdbool.h>
  6. #define ListEmpty -2
  7.  
  8. struct Node;
  9. typedef struct Node *PtrToNode;
  10. typedef PtrToNode List;
  11. typedef PtrToNode Position;
  12.  
  13. List MakeEmpty(List L);
  14. bool IsEmpty(List L);
  15. bool IsLast(Position P, List L);
  16. Position Header(List L);
  17. Position Advance(Position P);
  18. ElementType Retrieve(Position P);
  19. void DeleteList(List L);
  20. void PrintList(const List L);
  21. void Insert(ElementType X, List L, Position P);
  22. void MoveNode(List L1, List L2);//将表L2中的头节点移动成为L1的尾节点
  23. void RadixSort(List L,int max);//最终基数排序函数,输入链表L,将L排序得到新的排序链表L,其中max是待排元素最高有多少位
  24. #endif // !RADIX_SORT_H

其中RadixSort是最终排序函数,调用它即可排序。

库函数RadixSort.c

  1. #include "RadixSort.h"
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<malloc.h>
  5. #include<math.h>
  6. #include"fatal.h"
  7. struct Node
  8. {
  9. ElementType Element;
  10. Position Next;
  11. };
  12.  
  13. //初始化链表
  14. List MakeEmpty(List L)
  15. {
  16. if (L != NULL)
  17. DeleteList(L);//如果链表非空,则删除链表
  18. L = malloc(sizeof(struct Node));
  19. if (L == NULL)
  20. FatalError("Out of memory!");
  21. L->Next = NULL;
  22. return L;
  23. }
  24. //判断链表是否为空
  25. bool IsEmpty(List L)
  26. {
  27. return L->Next == NULL;
  28. }
  29.  
  30. //判断当前指针P是否指向链表最后一个元素
  31. bool IsLast(Position P, List L)
  32. {
  33. return P->Next == NULL;
  34. }
  35.  
  36. //获取链表头
  37. Position Header(List L)
  38. {
  39. return L;
  40. }
  41.  
  42. //获取位置P的下一个位置
  43. Position Advance(Position P)
  44. {
  45. return P->Next;
  46. }
  47.  
  48. //提取位置P处结构里面的值
  49. ElementType Retrieve(Position P)
  50. {
  51. return P->Element;
  52. }
  53.  
  54. //删除链表
  55. void DeleteList(List L)
  56. {
  57. Position P, Temp;
  58. P = L->Next;
  59. L->Next = NULL;
  60. while (P != NULL)
  61. {
  62. Temp = P->Next;
  63. free(P);
  64. P = Temp;
  65. }
  66. }
  67.  
  68. //打印链表
  69. void PrintList(const List L)
  70. {
  71. Position P = Header(L);
  72. if (IsEmpty(L))
  73. printf("Empty list\n");
  74. else
  75. {
  76. do
  77. {
  78. P = Advance(P);
  79. printf("%d ", Retrieve(P));
  80. } while (!IsLast(P, L));
  81. printf("\n");
  82. }
  83. }
  84.  
  85. //插入元素X到位置P后面
  86. void Insert(ElementType X, List L, Position P)
  87. {
  88. Position TmpCell;
  89. TmpCell = malloc(sizeof(struct Node));
  90. if (TmpCell == NULL)
  91. FatalError("Out of Space!!!");
  92. TmpCell->Element = X;
  93. TmpCell->Next = P->Next;
  94. P->Next = TmpCell;
  95. }
  96.  
  97. void MoveNode(List L1, List L2)
  98. {
  99. //将表L2中的头节点移动成为L1的尾节点
  100. Position Tmp1 = L1;
  101. Position Tmp2;
  102. if (IsEmpty(L2)) exit(ListEmpty);
  103. while (!IsLast(Tmp1,L1))
  104. Tmp1 = Tmp1->Next;//使Tmp1指向L1表尾
  105. Tmp2 = L2->Next;
  106. L2->Next = Tmp2->Next;
  107. Tmp1->Next = Tmp2;
  108. Tmp2->Next = NULL;
  109. }
  110.  
  111. void RadixSort(List L,int max)
  112. {
  113. //if (IsEmpty(L)) return L; //如果要排序的链表L是空表,则不排序
  114. int i,j, TmpSub;//Tmpsub存储数的个位、十位、百位
  115. ElementType FirstElement;//存储链表的第一个元素
  116.  
  117. List Bucket[];//开辟10个桶,依次为0~9
  118. for (i = ; i < ; i++) Bucket[i] = MakeEmpty(NULL);//对10桶进行初始化,每一个数组都是一个链表
  119. for (i = ; i < max; i++)//开始提取每一位数的个位、十位、百位
  120. {
  121. while (!IsEmpty(L))//当L中的元素被取光了,则循环结束
  122. {
  123. FirstElement = L->Next->Element;//取出第一个节点的数据
  124. TmpSub = (int)(FirstElement / pow(, i)) % ;//依次取出个十百位数字
  125. MoveNode(Bucket[TmpSub], L);//将L中的节点依次移到对应的桶中
  126. }
  127. for (j = ; j < ; j++) //将桶中的数再次移动到L中
  128. {
  129. while (!IsEmpty(Bucket[j])) MoveNode(L, Bucket[j]);
  130. }
  131. }
  132. for (i = ; i < ; i++) free(Bucket[i]) ;//释放掉10个桶
  133. }

测试函数Test_Radix_Sort.c

  1. #include<stdio.h>
  2. #include "RadixSort.h"
  3. #include"fatal.h"
  4. #include<time.h>
  5.  
  6. int main()
  7. {
  8. int amount;
    List L; Position P;
  9. L = MakeEmpty(NULL);//初始化链表
  10. P = L;
  11. if (L == NULL) Error("Out of Space!!!");
  12. printf("随机生成多少位数:");
  13. scanf_s("%d", &amount);
  14. srand((unsigned)time(NULL));
  15. for (int i = ; i < amount; i++)
  16. {
  17. Insert(rand() % , L, P);
  18. P = Advance(P);
  19. }
  20. printf("排序前的结果:");
  21. PrintList(L);
  22. RadixSort(L,);//调用排序函数排序
  23. printf("基数排序后的结果:");
  24. PrintList(L);
  25. }

排序算法----基数排序(RadixSort(L,max))单链表版本的更多相关文章

  1. 经典排序算法 - 基数排序Radix sort

    经典排序算法 - 基数排序Radix sort 原理类似桶排序,这里总是须要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,临时忽视十位数 比如 待排序数组[ ...

  2. 学习排序算法(一):单文档方法 Pointwise

    学习排序算法(一):单文档方法 Pointwise 1. 基本思想 这样的方法主要是将搜索结果的文档变为特征向量,然后将排序问题转化成了机器学习中的常规的分类问题,并且是个多类分类问题. 2. 方法流 ...

  3. 使用 js 实现十大排序算法: 基数排序

    使用 js 实现十大排序算法: 基数排序 基数排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  4. 排序算法----基数排序(RadixSort(L))单链表智能版本

    转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...

  5. 已知单链表的数据元素为整型数且递增有序,L为单链表的哨兵指针。编写算法将表中值大于X小于Y的所有结点的顺序逆置。(C语言)

    对此题目的完整示例可直接运行代码如下: #include <stdio.h> #include <stdlib.h> typedef struct LNode{ int dat ...

  6. 基本排序算法——基数排序java实现

    基数排序 package basic.sort; import java.util.Arrays; import java.util.Random; public class RadixSort { ...

  7. 八大排序算法——基数排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演 二.思路分析 基数排序第i趟将待排数组里的每个数的i位数放到tempj(j=1-10)队列中,然后再从这十个队列中取出数据,重新放到原数组里,直到i大于待排数的最大位数. 1.数组里的数最 ...

  8. 排序算法-基数排序(Java)

    package com.rao.sort; import java.util.*; /** * @author Srao * @className RadioSort * @date 2019/12/ ...

  9. [转] 经典排序算法 - 基数排序Radix sort

    原理类似桶排序,这里总是需要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数 例如 待排序数组[62,14,59,88,16]简单点五个数字 分 ...

随机推荐

  1. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  2. 日常css技巧小结(2)-- inline-block带来的迷惑

    一.问题描述 在平时布局中,inline-block使用的频率比很高,主要是因为可以让行标签设置宽高.我在布局过程中,发现了两个“问题”, 1行标签.display:inline-block之后的行标 ...

  3. [摘录]第三部分 IBM文化(1)

    第二十章 论公司文化如果是在20世纪90年代初期,当一个人看见或者听到“IBM”时,他会联想到什么呢?或许是“大计算机”.“个人电脑”或者“ThinkPads”.但是,他们同时也必然会想到“大公司”. ...

  4. Oracle数据库升级(10.2.0.4->11.2.0.4)

    环境: RHEL5.4 + Oracle 10.2.0.4 目的: 在本机将数据库升级到11.2.0.4 之前总结的Oracle数据库异机升级:http://www.cnblogs.com/jyzha ...

  5. Django admin美化插件suit应用[原创]

    前言 由于比较懒,自己弄了一个用户验证,没有自己写后台,用了django自带的user认证,并通过admin直接进行管理,但默认的admin并不漂亮,于是使用了这个django-suit插件,效果对比 ...

  6. Rafy 框架 - 执行SQL或存储过程

    有时候,开发者不想通过实体来操作数据库,而是希望通过 SQL 语句或存储过程来直接访问数据库.Rafy 也提供了一组 API 来方便实现这类需求. IDbAccesser 接口 为了尽量屏蔽各数据库中 ...

  7. Kafka消息时间戳(kafka message timestamp)

    最近碰到了消息时间戳的问题,于是花了一些功夫研究了一下,特此记录一下.   Kafka消息的时间戳 在消息中增加了一个时间戳字段和时间戳类型.目前支持的时间戳类型有两种: CreateTime 和 L ...

  8. SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

    相信很多人进行数据存储时,会遇上如标题的异常错误. 其实也不算上一个错误. 当你的程序中有宣告一个字段的数据类型为DateTime时,但你又没有赋值给它,就进行存储时,它就会得到这样一个结果. 看看下 ...

  9. shell编程

    最吸引人的莫过于及时看到成果的努力,echo就是最好的初学者反馈函数,因为它的存在你可以及时的打印出结果. 1.分支 if[ ]:then elif ;then else fi 2.简单的循环,循环是 ...

  10. 开源跨平台IOT通讯框架ServerSuperIO,集成到NuGet程序包管理器,以及Demo使用说明

          物联网涉及到各种设备.各种传感器.各种数据源.各种协议,并且很难统一,那么就要有一个结构性的框架解决这些问题.SSIO就是根据时代发展的阶段和现实实际情况的结合产物. 各种数据信息,如下图 ...