今天在头条看一个很有意思的排序算法【基数排序】,以前所学习的排序算法都是基于数值对比的方式排序的,而这个算法挺有意思的非常独特。但从网上看到的例子通常是对个位,十位处理,并转为对应的桶索引的方式实现,这里将此算法用C#实现,并以位运算的新方式实现。

一.代码实现

        static void Main(string[] args)
{
//待排序数组
List<int> arrlist = new List<int>() { , , , , , , , , , , , };
int Number = ; //基数 网上教材都是基于个位,十位,百位进行运算,这里通过位数计算
int NumCount = << Number; //桶数 位数是3那么桶数是8, 位数是4那么桶数是16
List<List<int>> intList = new List<List<int>>(); //建立好桶
for (int i = ; i < NumCount; i++)
{
intList.Add(new List<int>());
}
int LayerCount = ; //位数划分组数(计算方法:数组最大值为95,对应二进制为:1011111,基数为3的话,可以分为1,011,111; 组数为3)
//算法实现-----算法复杂度(nxm)
for (int k = ; k <= LayerCount; k++) //最大整数最高位数划分组数
{
intList.ForEach(tt => tt.Clear());
foreach (var item in arrlist)
{
int index = item & (( << k * Number) - ); //左移加与位运算 求桶索引
index = index >> (k - ) * Number;//右移加与运算 求桶索引
intList[index].Add(item);
}
arrlist.Clear();
for (int i = ; i < NumCount; i++)
{
for (int j = ; j <intList[i].Count; j++)
{
arrlist.Add(intList[i][j]);
}
}
}
//输出
arrlist.ForEach(tt=>Console.WriteLine(tt));
Console.ReadKey();
}

二.输出排序结果:

三 .基数排序算法介绍:

基数排序的两个关键要点:

(1)基:被排序的元素的“个位”“十位”“百位”,暂且叫“基”,栗子中“基”的个数是2(个位和十位);

画外音:来自野史,大神可帮忙修正。

(2)桶:“基”的每一位,都有一个取值范围,栗子中“基”的取值范围是0-9共10种,所以需要10个桶(bucket),来存放被排序的元素;

基数排序的算法步骤为:

FOR (每一个基) {

//循环内,以某一个“基”为依据

第一步:遍历数据集arr,将元素放入对应的桶bucket

第二步:遍历桶bucket,将元素放回数据集arr

}

更具体的,对应到上面的栗子,“基”有个位和十位,所以,FOR循环会执行两次。

【第一次:以“个位”为依据】

画外音:上图中标红的部分,个位为“基”。

第一步:遍历数据集arr,将元素放入对应的桶bucket;

操作完成之后,各个桶会变成上面这个样子,即:个位数相同的元素,会在同一个桶里。

第二步:遍历桶bucket,将元素放回数据集arr;

画外音:需要注意,先入桶的元素要先出桶。

操作完成之后,数据集会变成上面这个样子,即:整体按照个位数排序了。

画外音:个位数小的在前面,个位数大的在后面。

【第二次:以“十位”为依据】

画外音:上图中标红的部分,十位为“基”。

第一步:依然遍历数据集arr,将元素放入对应的桶bucket;

操作完成之后,各个桶会变成上面这个样子,即:十位数相同的元素,会在同一个桶里。

第二步:依然遍历桶bucket,将元素放回数据集arr;

操作完成之后,数据集会变成上面这个样子,即:整体按照十位数也排序了。

画外音:十位数小的在前面,十位数大的在后面。

首次按照个位从小到大,第二次按照十位从小到大,即:排序结束。

神奇不神奇!!!

几个小点:

(1)基的选取,可以先从个位开始,也可以先从十位开始,结果是一样的;

(2)基数排序,是一种稳定的排序;

(3)时间复杂度,可以认为是线性的O(n);

PCB 挺有意思的基数排序----C#代码实现的更多相关文章

  1. 现在觉得IT还挺有意思

    前两天刚刚接触编程,用的是C#.开始确实枯燥,但是今天的感觉就好多了,还挺有意思.根据老师讲的课程自己编写了小程序,运行起来还不错.在这里分享下. 关于时间安排的小程序: int sj; int aa ...

  2. SAP密码策略挺有意思

    很多系统管理员可能都知道通过RZ10可以配置SAP的密码策略.例如:密码里包含的大小写字符.数字.特殊字符.密码长度.密码不能和前多少次的密码相同.不能和之前的密码有多少位相似等但是你知道吗?其实还有 ...

  3. 让reddit/r/programming炸锅的一个帖子,还是挺有意思的

    这是原帖 http://www.reddit.com/r/programming/comments/358tnp/five_programming_problems_every_software_en ...

  4. MySQL 挺有意思

    1, 修改密码 mysql -u root -p update user set Password = PASSWORD('NEWPWD') WHERE user = 'root'; FLUSH PR ...

  5. 挺有意思的Blog

    http://blog.csdn.net/dawanganban/article/details/19925449 http://www.syslog.org/ https://baoz.net/li ...

  6. 感觉挺有意思的SQL题目

    1.有如下数据,要求查询每个班最低分和最高分,并将最高分与最低分显示为同一列 ID Student CourseName Score1 张三 English 802 张三 Math 703 张三 Ch ...

  7. 挺有意思的HBase日志+Splunk

    如题,转载自: http://hi.baidu.com/harry_lime/item/10cf2c174853c7ea39cb3042 如何模拟拔盘操作 Linux has a nifty way ...

  8. POJ3318【随机化算法挺有意思】

    题目链接:http://poj.org/problem?id=3318 http://meizhe143.blog.163.com/blog/static/3893836200710299512136 ...

  9. 由consequence忽然发现英语也挺有意思

    con- 是拉丁语前缀, 有 with, together 的意思. con- 和 com- 一样的. 只是因为 在 b p m 前发 m 音更方便, 所以这些音前的 con- 变为 com- (例 ...

随机推荐

  1. 关于SPFA的双端队列优化

    7.11 Update 我做题的时候发现这样写会RE 因为在使用双端队列优化SPFA的时候 在将一个点加入队列的时候,如果队列已经空了 那么一旦出现dis[Q.front()]就会RE 可以这样修改 ...

  2. Address already in use: JVM_Bind:8080错误的解决办法

    解决办法:先到命令行查找8080端口号被那个占用,输入后面的命令:netstat -ano 查到 然后到任务管理器把PID为20904的进程给结束掉,就OK了 -------------------- ...

  3. Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'.

    在连接数据库时,使用了最新版本的mysql-Connector,所以导致老版本的“com.mysql.jdbc.Drive”不可行,要改为“com.mysql.cj.jdbc.Driver”

  4. Java 字符串总结

    三种字符串类:String,StringBuilder,StringBuffer String类 1. 常用构造器 构造器   public String(char value[])   public ...

  5. 解决ASP.NET Core部署到IIS,更新项目"另一个程序正在使用此文件,进程无法访问"

    问题:部署到IIS上的ASP.NET Core项目,在更新的时候会进程占用的错误 初步解决方案: 1,关闭应用程序池 2,关闭网站 3,更新项目 缺点:网站没法访问,部署项目停的时间过长 查询官方文档 ...

  6. SpringSecurity 获取认证信息 和 认证实现

    JdbcDaoImpl 实现获取认证信息 PasswordEncoder 实现具体认证过程

  7. linux 简单实用小操作

    mysql改密码 通过root以后,(root密码忘记就没法了) alter user username@'%' identified by 'password' 端口被占用 sudo fuser - ...

  8. http://localhost/main/company/jurtion---外卖权限添加

    http://localhost/main/company/jurtion---外卖权限添加

  9. Android layer-list:联合shape(2)

     Android layer-list:联合shape(2) 附录文章3简单说明了Android layer-list的用法,现在把Android layer-list联合shape做出一些特殊的 ...

  10. hammerjs & Swiper & touch & gesture

    hammerjs https://hammerjs.github.io/getting-started/ http://hammerjs.github.io/recognizer-swipe/ Swi ...