排序算法----基数排序(RadixSort(L))单链表智能版本
转载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))单链表智能版本的更多相关文章
- 经典排序算法 - 基数排序Radix sort
经典排序算法 - 基数排序Radix sort 原理类似桶排序,这里总是须要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,临时忽视十位数 比如 待排序数组[ ...
- 使用 js 实现十大排序算法: 基数排序
使用 js 实现十大排序算法: 基数排序 基数排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- 排序算法----基数排序(RadixSort(L,max))单链表版本
转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...
- 基于visual Studio2013解决算法导论之020单链表
题目 单链表操作 解决代码及点评 #include <iostream> using namespace std; struct LinkNode { public: LinkNo ...
- 经典算法(三) 单链表 反转 & 是否相交/成环 & 求交点 等
参考文章: 判断链表是否相交:http://treemanfm.iteye.com/blog/2044196 一.单链表反转 链表节点 public class Node { private int ...
- 算法总结之 将单链表的每K个节点之间逆序
给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点 思路: 如果k的值小于2,不调整.k<1 没有意义,k==1代 ...
- 算法总结之 在单链表和双链表中删除倒数第k个节点
分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...
- 基本排序算法——基数排序java实现
基数排序 package basic.sort; import java.util.Arrays; import java.util.Random; public class RadixSort { ...
- 八大排序算法——基数排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演 二.思路分析 基数排序第i趟将待排数组里的每个数的i位数放到tempj(j=1-10)队列中,然后再从这十个队列中取出数据,重新放到原数组里,直到i大于待排数的最大位数. 1.数组里的数最 ...
随机推荐
- Java中的多态
1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal {public abstract void Say();} 子类: public class ...
- solr_架构案例【京东站内搜索】(附程序源代码)
注意事项:首先要保证部署solr服务的Tomcat容器和检索solr服务中数据的Tomcat容器,它们的端口号不能发生冲突,否则web程序是不可能运行起来的. 一:solr服务的端口号.我这里的sol ...
- 在Linux虚拟机下配置tomcat
1.到Apache官网下载tomcat http://tomcat.apache.org/download-80.cgi 博主我下载的是tomcat8 博主的jdk是1.8 如果你们的jdk是1.7或 ...
- RxJS + Redux + React = Amazing!(译二)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...
- 深究标准IO的缓存
前言 在最近看了APUE的标准IO部分之后感觉对标准IO的缓存太模糊,没有搞明白,APUE中关于缓存的部分一笔带过,没有深究缓存的实现原理,这样一本被吹上天的书为什么不讲透彻呢?今天早上爬起来赶紧找了 ...
- [C#] 简单的 Helper 封装 -- CookieHelper
using System; using System.Web; namespace ConsoleApplication5 { /// <summary> /// Cookie 助手 // ...
- System.Guid ToString五中格式
参考:https://msdn.microsoft.com/en-us/library/97af8hh4.aspx 测试代码: using System; using System.Collectio ...
- angluarjs2项目生成内容合并到asp.net mvc4项目中一起发布
应用场景 angular2(下文中标注位NG2)项目和.net mvc项目分别开发,前期采用跨域访问进行并行开发,后期只需要将NG2项目的生产版本合并到.net项目. NG2项目概述 ng2项目采用的 ...
- 2013 Asia Changsha Regional Contest---Josephina and RPG(DP)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4800 Problem Description A role-playing game (RPG and ...
- autocomplete的使用
autocomplete使用分为本地调用方法和读取远程读取数据源的方法 (1)本地调用方法 <script src="Scripts/jquery-1.4.1.min.js" ...