排序算法----基数排序(RadixSort(L,max))单链表版本
转载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:
- #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>
- #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);
- void Insert(ElementType X, List L, Position P);
- void MoveNode(List L1, List L2);//将表L2中的头节点移动成为L1的尾节点
- void RadixSort(List L,int max);//最终基数排序函数,输入链表L,将L排序得到新的排序链表L,其中max是待排元素最高有多少位
- #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");
- }
- }
- //插入元素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 max)
- {
- //if (IsEmpty(L)) return L; //如果要排序的链表L是空表,则不排序
- int i,j, TmpSub;//Tmpsub存储数的个位、十位、百位
- ElementType FirstElement;//存储链表的第一个元素
- List Bucket[];//开辟10个桶,依次为0~9
- for (i = ; i < ; i++) Bucket[i] = MakeEmpty(NULL);//对10桶进行初始化,每一个数组都是一个链表
- for (i = ; i < max; 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,max))单链表版本的更多相关文章
- 经典排序算法 - 基数排序Radix sort
经典排序算法 - 基数排序Radix sort 原理类似桶排序,这里总是须要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,临时忽视十位数 比如 待排序数组[ ...
- 学习排序算法(一):单文档方法 Pointwise
学习排序算法(一):单文档方法 Pointwise 1. 基本思想 这样的方法主要是将搜索结果的文档变为特征向量,然后将排序问题转化成了机器学习中的常规的分类问题,并且是个多类分类问题. 2. 方法流 ...
- 使用 js 实现十大排序算法: 基数排序
使用 js 实现十大排序算法: 基数排序 基数排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- 排序算法----基数排序(RadixSort(L))单链表智能版本
转载http://blog.csdn.net/Shayabean_/article/details/44885917博客 先说说基数排序的思想: 基数排序是非比较型的排序算法,其原理是将整数按位数切割 ...
- 已知单链表的数据元素为整型数且递增有序,L为单链表的哨兵指针。编写算法将表中值大于X小于Y的所有结点的顺序逆置。(C语言)
对此题目的完整示例可直接运行代码如下: #include <stdio.h> #include <stdlib.h> typedef struct LNode{ int dat ...
- 基本排序算法——基数排序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)
package com.rao.sort; import java.util.*; /** * @author Srao * @className RadioSort * @date 2019/12/ ...
- [转] 经典排序算法 - 基数排序Radix sort
原理类似桶排序,这里总是需要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数 例如 待排序数组[62,14,59,88,16]简单点五个数字 分 ...
随机推荐
- Android动画效果之初识Property Animation(属性动画)
前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...
- 日常css技巧小结(2)-- inline-block带来的迷惑
一.问题描述 在平时布局中,inline-block使用的频率比很高,主要是因为可以让行标签设置宽高.我在布局过程中,发现了两个“问题”, 1行标签.display:inline-block之后的行标 ...
- [摘录]第三部分 IBM文化(1)
第二十章 论公司文化如果是在20世纪90年代初期,当一个人看见或者听到“IBM”时,他会联想到什么呢?或许是“大计算机”.“个人电脑”或者“ThinkPads”.但是,他们同时也必然会想到“大公司”. ...
- 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 ...
- Django admin美化插件suit应用[原创]
前言 由于比较懒,自己弄了一个用户验证,没有自己写后台,用了django自带的user认证,并通过admin直接进行管理,但默认的admin并不漂亮,于是使用了这个django-suit插件,效果对比 ...
- Rafy 框架 - 执行SQL或存储过程
有时候,开发者不想通过实体来操作数据库,而是希望通过 SQL 语句或存储过程来直接访问数据库.Rafy 也提供了一组 API 来方便实现这类需求. IDbAccesser 接口 为了尽量屏蔽各数据库中 ...
- Kafka消息时间戳(kafka message timestamp)
最近碰到了消息时间戳的问题,于是花了一些功夫研究了一下,特此记录一下. Kafka消息的时间戳 在消息中增加了一个时间戳字段和时间戳类型.目前支持的时间戳类型有两种: CreateTime 和 L ...
- SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
相信很多人进行数据存储时,会遇上如标题的异常错误. 其实也不算上一个错误. 当你的程序中有宣告一个字段的数据类型为DateTime时,但你又没有赋值给它,就进行存储时,它就会得到这样一个结果. 看看下 ...
- shell编程
最吸引人的莫过于及时看到成果的努力,echo就是最好的初学者反馈函数,因为它的存在你可以及时的打印出结果. 1.分支 if[ ]:then elif ;then else fi 2.简单的循环,循环是 ...
- 开源跨平台IOT通讯框架ServerSuperIO,集成到NuGet程序包管理器,以及Demo使用说明
物联网涉及到各种设备.各种传感器.各种数据源.各种协议,并且很难统一,那么就要有一个结构性的框架解决这些问题.SSIO就是根据时代发展的阶段和现实实际情况的结合产物. 各种数据信息,如下图 ...