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

先说说基数排序的思想

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

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

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

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

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

头文件fatal.h:

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

头文件RadixSort.h

 typedef int ElementType;
#ifndef RADIX_SORT_H
#define RADIX_SORT_H #include<stdbool.h>
#include<assert.h>
#define ListEmpty -2 struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position; List MakeEmpty(List L);
bool IsEmpty(List L);
bool IsLast(Position P, List L);
Position Header(List L);
Position Advance(Position P);
ElementType Retrieve(Position P);
void DeleteList(List L);
void PrintList(const List L);
ElementType Max_LinkedList(List L);//获取链表的最大值
int Get_Num_Length(ElementType Num);//获取某个数的位数
void Insert(ElementType X, List L, Position P);
void MoveNode(List L1, List L2);//将表L2中的头节点移动成为L1的尾节点
void RadixSort(List L);//最终基数排序函数,输入链表L,将L排序得到新的排序链表L
#endif // !RADIX_SORT_H

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

库函数RadixSort.c

 #include "RadixSort.h"
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<math.h>
#include"fatal.h" //定义结构体
struct Node
{
ElementType Element;
Position Next;
}; //初始化链表
List MakeEmpty(List L)
{
if (L != NULL)
DeleteList(L);//如果链表非空,则删除链表
L = malloc(sizeof(struct Node));
if (L == NULL)
FatalError("Out of memory!");
L->Next = NULL;
return L;
}
//判断链表是否为空
bool IsEmpty(List L)
{
return L->Next == NULL;
} //判断当前指针P是否指向链表最后一个元素
bool IsLast(Position P, List L)
{
return P->Next == NULL;
} //获取链表头
Position Header(List L)
{
return L;
} //获取位置P的下一个位置
Position Advance(Position P)
{
return P->Next;
} //提取位置P处结构里面的值
ElementType Retrieve(Position P)
{
return P->Element;
} //删除链表
void DeleteList(List L)
{
Position P, Temp;
P = L->Next;
L->Next = NULL;
while (P != NULL)
{
Temp = P->Next;
free(P);
P = Temp;
}
} //打印链表
void PrintList(const List L)
{
Position P = Header(L);
if (IsEmpty(L))
printf("Empty list\n");
else
{
do
{
P = Advance(P);
printf("%d ", Retrieve(P));
} while (!IsLast(P, L));
printf("\n");
}
} //获取链表的最大值
ElementType Max_LinkedList(List L)
{
if (IsEmpty(L))
Error("Empty List")
else
{
Position P = L->Next;
ElementType Max = P->Element;
while (P != NULL)
{
if (P->Element > Max)
Max = P->Element;
P = P->Next;
}
return Max;
}
} //计算一个数有多少位
int Get_Num_Length(ElementType Num)
{
int Length=;
while ((Num /= ) != ) Length++;
return Length;
} //插入元素X到位置P后面
void Insert(ElementType X, List L, Position P)
{
Position TmpCell;
TmpCell = malloc(sizeof(struct Node));
if (TmpCell == NULL)
FatalError("Out of Space!!!");
TmpCell->Element = X;
TmpCell->Next = P->Next;
P->Next = TmpCell;
} void MoveNode(List L1, List L2)
{
//将表L2中的头节点移动成为L1的尾节点
Position Tmp1 = L1;
Position Tmp2;
if (IsEmpty(L2)) exit(ListEmpty);
while (!IsLast(Tmp1,L1))
Tmp1 = Tmp1->Next;//使Tmp1指向L1表尾
Tmp2 = L2->Next;
L2->Next = Tmp2->Next;
Tmp1->Next = Tmp2;
Tmp2->Next = NULL;
} //基数排序核心代码
void RadixSort(List L)
{
int i,j,Max_Length, TmpSub;//Tmpsub存储数的个位、十位、百位
ElementType FirstElement;//存储链表的第一个元素
Max_Length = Get_Num_Length(Max_LinkedList(L));
List Bucket[];//开辟10个桶,依次为0~9
for (i = ; i < ; i++) Bucket[i] = MakeEmpty(NULL);//对10桶进行初始化,每一个数组都是一个链表
for (i = ; i < Max_Length; i++)//开始提取每一位数的个位、十位、百位
{
while (!IsEmpty(L))//当L中的元素被取光了,则循环结束
{
FirstElement = L->Next->Element;//取出第一个节点的数据
TmpSub = (int)(FirstElement / pow(, i)) % ;//依次取出个十百位数字
MoveNode(Bucket[TmpSub], L);//将L中的节点依次移到对应的桶中
}
for (j = ; j < ; j++) //将桶中的数再次移动到L中
{
while (!IsEmpty(Bucket[j])) MoveNode(L, Bucket[j]);
}
}
for (i = ; i < ; i++) free(Bucket[i]) ;//释放掉10个桶
}

测试函数Test_Radix_Sort.c

 #include<stdio.h>
#include "RadixSort.h"
#include"fatal.h"
#include<time.h> int main()
{
int amount;
List L; Position P;
L = MakeEmpty(NULL);//初始化链表
P = L;
if (L == NULL) Error("Out of Space!!!");
printf("随机生成多少位数:");
scanf_s("%d", &amount);
srand((unsigned)time(NULL));
for (int i = ; i < amount; i++)
{
Insert(rand()%, L, P);
P = Advance(P);
}
printf("排序前的结果:");
PrintList(L);
RadixSort(L);//调用排序函数排序
printf("基数排序后的结果:");
PrintList(L);
}

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

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

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

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

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

  3. 排序算法----基数排序(RadixSort(L,max))单链表版本

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

  4. 基于visual Studio2013解决算法导论之020单链表

     题目 单链表操作 解决代码及点评 #include <iostream> using namespace std; struct LinkNode { public: LinkNo ...

  5. 经典算法(三) 单链表 反转 & 是否相交/成环 & 求交点 等

    参考文章: 判断链表是否相交:http://treemanfm.iteye.com/blog/2044196 一.单链表反转 链表节点 public class Node { private int ...

  6. 算法总结之 将单链表的每K个节点之间逆序

    给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点 思路: 如果k的值小于2,不调整.k<1 没有意义,k==1代 ...

  7. 算法总结之 在单链表和双链表中删除倒数第k个节点

    分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...

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

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

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

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

随机推荐

  1. ASP.NET Web API 跨域访问(CORS)

    一.客户端用JSONP请求数据 如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的: {"YourSignatu ...

  2. Linux虚拟机的安装(使用Centos6.3)

    1.什么是虚拟机? 虚拟机指通过软件模拟的具有完整硬件系统功能的.运行在一个完全隔离环境中的完整计算机系统 2.安装Linux虚拟机前要做的准备 2.1:一台windows环境的pc 2.2:下载VM ...

  3. SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论

    异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#signalR 后台创建了一个DntHub的集线器 前台在调用的时候出现了问题(经检查是代理对象 ...

  4. AFNetworking 3.0 源码解读(六)之 AFHTTPSessionManager

    AFHTTPSessionManager相对来说比较好理解,代码也比较短.但却是我们平时可能使用最多的类. AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilit ...

  5. C++随笔:.NET CoreCLR之GC探索(3)

    有几天没写GC相关的文章了哈,今天我讲GC的方式是通过一个小的Sample来讲解,这个小的示例代码只有全部Build成功了才会有.地址为D:\coreclr2\coreclr\bin\obj\Wind ...

  6. (翻译)FIFO In Hardware

    翻译一些自己觉得有价值的材料,工作中碰到英语大多数是读,基本没有写或者翻的,翻得不好不到位的敬请指摘. 同时也附原文以供参考. http://electronics.stackexchange.com ...

  7. IT运维监控解决方案介绍

    现状 •小公司/ 创业团队< 500台服务器规模 开源方案:Zabbix.Nagios.Cacti- 云服务提供商:监控宝.oneAlert等 •BAT级别> 10万台服务器 投 ...

  8. jQuery可拖拽3D万花筒旋转特效

    这是一个使用了CSS3立体效果的强大特效,本特效使用jQuery跟CSS3 transform来实现在用户鼠标按下拖动时,环形图片墙可以跟随鼠标进行3D旋转动画. 效果体验:http://hovert ...

  9. listview下拉刷新和上拉加载更多的多种实现方案

    listview经常结合下来刷新和上拉加载更多使用,本文总结了三种常用到的方案分别作出说明. 方案一:添加头布局和脚布局        android系统为listview提供了addfootview ...

  10. MySQL数据库罕见的BUG——Can't get hostname for your address

    在连接mysql jdbc时候,抛出了 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communicat ...