• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 深入解析Radix Sort基数排序算法思想及C语言实现示例

深入解析Radix Sort基数排序算法思想及C语言实现示例

作者:zhoutk 字体:[增加 减小] 来源:互联网 时间:2017-05-28

zhoutk 通过本文主要向大家介绍了radix sort,radix,radix是什么意思,radix astragali,radix排泄等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

基本思想:

将待排数据中的每组关键字依次进行桶分配。
具体示例:

278、109、063、930、589、184、505、269、008、083
</div>

我们将每个数值的个位,十位,百位分成三个关键字: 278 -> k1(个位)=8,k2(十位)=7,k3=(百位)=2。

然后从最低位个位开始(从最次关键字开始),对所有数据的k1关键字进行桶分配(因为,每个数字都是 0-9的,因此桶大小为10),再依次输出桶中的数据得到下面的序列。

930、063、083、184、505、278、008、109、589、269
</div>

再对上面的序列接着进行针对k2的桶分配,输出序列为:

505、008、109、930、063、269、278、083、184、589
</div>

最后针对k3的桶分配,输出序列为:

008、063、083、109、184、269、278、505、589、930
</div>

效率分析:

基数排序的性能比桶排序要略差。每一次关键字的桶分配都需要O(N)的时间复杂度,而且分配之后得到新的关键字序列又需要O(N)的时间复杂度。假如待排数据可以分为d个关键字,则基数排序的时间复杂度将是O(d*2N) ,当然d要远远小于N,因此基本上还是线性级别的。基数排序的空间复杂度为O(N+M),其中M为桶的数量。一般来说N>>M,因此额外空间需要大概N个左右。

但是,对比桶排序,基数排序每次需要的桶的数量并不多。而且基数排序几乎不需要任何“比较”操作,而桶排序在桶相对较少的情况下,桶内多个数据必须进行基于比较操作的排序。因此,在实际应用中,基数排序的应用范围更加广泛。


举例:
假设我们有一些二元组(a,b),要对它们进行以a为首要关键字,b的次要关键字的排序。我们可以先把它们先按照首要关键字排序,分成首要关键字相同的若干堆。然后,在按照次要关键值分别对每一堆进行单独排序。最后再把这些堆串连到一起,使首要关键字较小的一堆排在上面。按这种方式的基数排序称为MSD(Most Significant Dight)排序。

第二种方式是从最低有效关键字开始排序,称为LSD(Least Significant Dight)排序。首先对所有的数据按照次要关键字排序,然后对所有的数据按照首要关键字排序。要注意的是,使用的排序算法必须是稳定的,否则就会取消前一次排序的结果。由于不需要分堆对每堆单独排序,LSD方法往往比MSD简单而开销小。下文介绍的方法全部是基于LSD的。

通常,基数排序要用到计数排序或者桶排序。使用计数排序时,需要的是Order数组。使用桶排序时,可以用链表的方法直接求出排序后的顺序。下面是一段用桶排序对二元组基数排序的程序:


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
struct data
{
  int key[2];
};
struct linklist
{
  linklist *next;
  data value;
  linklist(data v,linklist *n):value(v),next(n){}
  ~linklist() {if (next) delete next;}
};
void BucketSort(data *A,int N,int K,int y)
{
  linklist *Bucket[101],*p;//建立桶
  int i,j,k,M;
  M=K/100+1;
  memset(Bucket,0,sizeof(Bucket));
  for (i=1;i<=N;i++)
  {
    k=A[i].key[y]/M; //把A中的每个元素按照的范围值放入对应桶中
    Bucket[k]=new linklist(A[i],Bucket[k]);
  }
  for (k=j=0;k<=100;k++)
  {
    for (p=Bucket[k];p;p=p->next) j++;
    for (p=Bucket[k],i=1;p;p=p->next,i++)
      A[j-i+1]=p->value; //把桶中每个元素取出
    delete Bucket[k];
  }
}
void RadixSort(data *A,int N,int K)
{
  for (int j=1;j>=0;j--) //从低优先到高优先 LSD
    BucketSort(A,N,K,j);
}
int main()
{
  int N=100,K=1000,i;
  data *A=new data[N+1];
  for (i=1;i<=N;i++)
  {
    A[i].key[0]=rand()%K+1;
    A[i].key[1]=rand()%K+1;
  }
  RadixSort(A,N,K);
  for (i=1;i<=N;i++)
    printf("(%d,%d) ",A[i].key[0],A[i].key[1]);
  printf("\n");
  return 0;
}
</div>

基数排序是一种用在老式穿卡机上的算法。一张卡片有80列,每列可在12个位置中的任一处穿孔。排序器可被机械地"程序化"以检查每一迭卡片中的某一列,再根据穿孔的位置将它们分放12个盒子里。这样,操作员就可逐个地把它们收集起来。其中第一个位置穿孔的放在最上面,第二个位置穿孔的其次,等等。

对于一个位数有限的十进制数,我们可以把它看作一个多元组,从高位到低位关键字重要程度依次递减。可以使用基数排序对一些位数有限的十进制数排序。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入解析Radix Sort基数排序算法思想及C语言实现示例

相关文章

  • 2017-05-28使用C++递归求解跳台阶问题
  • 2017-05-28C++基础入门教程(九):函数指针之回调
  • 2017-05-28C++使用CriticalSection实现线程同步实例
  • 2017-05-28VC6.0如何创建以及调用动态链接库实例详解
  • 2017-05-28C 语言中实现环形缓冲区
  • 2017-05-28websocket++简单使用及实例分析
  • 2017-05-28C语言中的sscanf()函数使用详解
  • 2017-05-28c++连接mysql数据库的两种方法(ADO连接和mysql api连接)
  • 2017-05-28C++虚函数的实现机制分析
  • 2017-05-28C语言实现Linux下的socket文件传输实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++ 算法之希尔排序详解及实例
    • VC小技巧汇总之对话框技巧
    • 如何应用C++的函数对象
    • 关于C/C++中可变参数的详细介绍(va_list,va_start,va_arg,va_end)
    • C语言简单实现求n阶勒让德多项式的方法
    • 深入剖析Android中init进程实现的C语言源码
    • c++11新增的便利算法实例分析
    • c++ 探讨奶牛生子的问题
    • C++符号优先级(详细整理)
    • STL各个容器性能详细比较

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有