`

【转】基数排序

阅读更多

转自:http://www.cppblog.com/shongbee2/archive/2009/04/24/80992.html

 

今天学了基数排序,据说他的时间复杂度也是O(n),他的思路就是:
没有计数排序那么理想,我们的数据都比较集中,都比较大,一般是4,5位。基本没有小的数据。
那我们的处理很简单,你不是没有小的数据嘛。我给一个基数,例如个位,个位都是[0-10)范围内的。先对他进行归类,把小的放上面,大的放下面,然后个位排好了,在来看10位,我们也这样把小的放上面,大的放下面,依次内推,直到最高位排好。那么不就排好了吗?我们只需要做d(基数个数)的循环就可以了。时间复杂度相当于O(d * n) 因为d为常量,例如5位数,d就是5.所以近似为O(n)的时间复杂度。这次自己写个案例:

最初的数据

排好个位的数据

排好十位的数据

排好百位的数据

981

981

725

129

387

753

129

387

753

955

753

456

129

725

955

725

955

456

456

753

725

387

981

955

456

129

387

981

这里只需循环3次就出结果了。

<!--[if !supportLists]-->3.       <!--[endif]-->但是注意,我们必须要把个位排好。但是个位怎么排呢?这个是个问题。书上说的是一叠一叠的怎么合并,我是没有理解的。希望知道的有高手教我一下。

我是用的一个计数排序来排各位的,然后排十位。效率应该也低不到哪里去。呵呵。。

思路就这样咯。奉上源代码:

 

#include <stdio.h>
#include <stdlib.h>

//计数排序,npRadix为对应的关键字序列,nMax是关键字的范围。npData是具体要
//排的数据,nLen是数据的范围,这里必须注意npIndex和npData对应的下标要一致
//也就是说npIndex[1] 所对应的值为npData[1]
int RadixCountSort(int* npIndex, int nMax, int* npData, int nLen)
{
    //这里就不用说了,计数的排序。不过这里为了是排序稳定
    
//在标准的方法上做了小修改。

    int* pnCount  = (int*)malloc(sizeof(int)* nMax);        //保存计数的个数
    for (int i = 0; i < nMax; ++i)
    {
        pnCount[i] = 0;
    }
    for (int i = 0; i < nLen; ++i)    //初始化计数个数
    {
        ++pnCount[npIndex[i]];
    }

    for (int i = 1; i < 10; ++i)  //确定不大于该位置的个数。
    {
        pnCount[i] += pnCount[i - 1];
    }

    int * pnSort  = (int*)malloc(sizeof(int) * nLen);    //存放零时的排序结果。

    
//注意:这里i是从nLen-1到0的顺序排序的,是为了使排序稳定。
    for (int i = nLen - 1; i >= 0; --i)
    {
        --pnCount[npIndex[i]];        
        pnSort[pnCount[npIndex[i]]] = npData[i];
    }

    for (int i = 0; i < nLen; ++i)        //把排序结构输入到返回的数据中。
    {
        npData[i] = pnSort[i];
    }
    free(pnSort);                        //记得释放资源。
    free(pnCount);
    return 1;
}

//基数排序
int RadixSort(int* nPData, int nLen)
{
    //申请存放基数的空间
    int* nDataRadix    = (int*)malloc(sizeof(int) * nLen);

    int nRadixBase = 1;    //初始化倍数基数为1
    bool nIsOk = false//设置完成排序为false

    
//循环,知道排序完成
    while (!nIsOk)
    {
        nIsOk = true;
        nRadixBase *= 10;
        for (int i = 0; i < nLen; ++i)
        {
            nDataRadix[i] = nPData[i] % nRadixBase;
            nDataRadix[i] /= nRadixBase / 10;
            if (nDataRadix[i] > 0)
            {
                nIsOk = false;
            }
        }
        if (nIsOk)        //如果所有的基数都为0,认为排序完成,就是已经判断到最高位了。
        {
            break;
        }
        RadixCountSort(nDataRadix, 10, nPData, nLen);
    }

    free(nDataRadix);

    return 1;
}

int main()
{
    //测试基数排序。
    int nData[10] = {123,5264,9513,854,9639,1985,159,3654,8521,8888};
    RadixSort(nData, 10);
    for (int i = 0; i < 10; ++i)
    {
        printf("%d ", nData[i]);
    }
    printf("\n");

    system("pause");
    return 0;
}
分享到:
评论

相关推荐

    八种常见排序算法总结(转)

    直接插入排序,希尔排序,冒泡排序,快速排序,直接选择排序,堆排序,归并排序,基数排序,比较全面,转自blog.csdn.com/whuslei

    算法设计与分析汽车牌照课程设计报告

    此题目主要要求对汽车牌照进行基数排序,和用二分查找的思想进行查找,这两种方法思想并不难,但是要对汽车牌照进行排序和查找,此问题涉及到的主要问题是: 首先的问题就是,用何种存储结构对汽车信息和汽车牌照...

    sort:使用比 O(n*log(n)) 更快的混合基数排序提出的 Boost Sort 库

    种类使用比 O(n*log(n)) 更快的混合基数排序提出的 Boost Sort 库如果您使用的是 Windows,请将下面路径中的“/”替换为“”。 要安装,下载 boost,运行 bootstrap,然后将此库复制到 /libs/sort。 仅在 Windows 上...

    C语言经典算法大全(程序员必备).rar

    基数排序法 � 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表) 插补搜寻法 费氏搜寻法 � 矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵......

    数据结构实验-排序算法

    1、创建排序类。 2、提供操作:选择排序、冒泡排序、插入排序、基数排序、快速排序、归并排序。(快速排序、归并排序讲到之后再做) 3、*能够显示各种排序算法的中间过程。

    汽车牌照的排序与查找问题-数据结构与算法课程设计报告

    此程序要完成如下要求:选择一种数据结构来存储每个车辆的信息(如车主姓名,汽车等),在此基础上进行基数排序,而汽车牌照是由汉字、字母以及数字组成,即多关键字,其中字母和数字的比较是比较容易实现的,考虑到...

    经典常用算法(含代码)

    经典常用算法解析与实现,通过Java C语言分别实现各种算法,图文并茂,描述很详细! 主要包括如下算法,很全面! 河内塔 费式数列 巴斯卡三角形 三色棋 老鼠走迷官(一) 老鼠走迷官(二) ...基数排序等

    华南 数据结构上机实验代码 完整代码

    基数排序 实现图的存储结构 图的深度遍历 图的广度遍历 二叉排序树的复制 计算二叉树的结点个数 删除单链性表中值相同的多余结点 删除线性表中所有值为x的元素 Josephus问题 利用递归实现查找中序遍历序列...

    经典算法大全,常用的算法都在这里

    老掉牙 河内塔 费式数列 巴斯卡三角形 三色棋 老鼠走迷官(一) 老鼠走迷官(二) 骑士走棋盘 八个皇后 八枚银币 生命游戏 ...基数排序法 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜

    C语言经典算法大全(几十个经典案例,都有详尽代码)

    C语言经典几十个经典案例,都有详尽 河内塔 费式数列 巴斯卡三角形 三色棋 老鼠走迷官(一) 老鼠走迷官(二) 骑士走棋盘 八个皇后 八枚银币 生命游戏 ...基数排序法 循序搜寻法(使用卫兵)

    经典算法教程 举例详解

    基数排序法 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表) 插补搜寻法 费氏搜寻法 矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵 4N 魔方阵 2(2N+1) 魔方阵

    【超全!】图解Java数据结构和算法(共195集)【资料+视频+课件+代码+笔记】

    稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫...基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、...

    数据结构和算法动画演示

    基数排序 二叉树的建立 二叉排序树的生成 二叉排序树的删除 中序线索化二叉树 寻找中序线索化二叉树指定结点的前驱 寻找中序线索化二叉树指定结点的后继 构造哈夫曼树的算法模拟 构造哈夫曼树过程 树、森林和二叉树...

    C-Program-examples.rar_2维码 C语言_c 卡牌游戏_字串核对_背包问题_蒙塔卡罗法

    基数排序法 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表) 插补搜寻法 费氏搜寻法 矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵 4N 魔方阵 2(2N+1) 魔方阵 对...

    c语言经典算法包括老掉牙,汉诺塔,三色旗

    基数排序法 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表) 插补搜寻法 费氏搜寻法 矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵 4N 魔方阵 2(2N+1) 魔方阵

    c语言经典算法

    基数排序法 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表) 插补搜寻法 费氏搜寻法 矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵 4N 魔方阵 2(2N+1) 魔方阵

    C语言经典算法大全

    基数排序法  搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表) 插补搜寻法 费氏搜寻法  矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵 4N 魔方阵 2(2N+1) 魔方...

    数据结构和算法Flash动画演示

    单链表结点的删除,单链表结点的插入,图的深度优先遍历,基数排序,堆排序,头插法建单链表,寻找中序线索化二叉树指定结点的前驱,寻找中序线索化二叉树指定结点的后继,尾插法建表,希儿排序,开放定址法建立散...

    经典算法全部用C语言实现

    基数排序法 搜寻 循序搜寻法(使用卫兵) 二分搜寻法(搜寻原则的代表) 插补搜寻法 费氏搜寻法 矩阵 稀疏矩阵 多维矩阵转一维矩阵 上三角、下三角、对称矩阵 奇数魔方阵 4N 魔方阵 2(2N+1) 魔方阵

Global site tag (gtag.js) - Google Analytics