---恢复内容开始---

算法说明

珠排序是分布排序的一种。

说实在的,这个排序看起来特别的巧妙,同时也特别好理解,不过不太容易写成代码,哈哈。

这里其实分析的特别好了,我就不画蛇添足啦。  大家看一下这个分析,特别特别简单的。

然后我对于下面的代码做一下描述:

1、找到数组的最大值(20-23行代码)

2、创建珠排序的容器,并且进行初始化(28-34行代码)

3、进行排序(39-44行代码),这里是珠排序的核心,也不太好解释,所以还是举例子啦。

例如排序的数组是int[] arr = { 2, 3, 4, 2, 7, 4, 1, 2, 3, 8 };

那么,通过代码我们发现,第一层循环的是arr数组,第二层循环的其实是arr数组中的值。那么

当i=0;num=2时,有:

j=0时,grid[0][0] = '*';

j=1时,grid[0][1] = '*';

接着

当i=1;num=3时,有:

j=0时,grid[1][0] = '*';

j=1时,grid[1][1] = '*';

j=2时,grid[0][2] = '*';

注意啦,j=0和1时,levelcount[j]都是为1的。 而j=2时,levelcount[j]为0.

继续……

当i=2;num=4时,有:

j=0时,grid[2][0]='*';

j=1时,grid[2][1]='*';

j=2时,grid[1][2] = '*';

j=3时,grid[0][3] = '*'

...

....

.....

以此类推,最终得出最终排序的结果

再次感叹,这种排序真的很巧妙啊。

当然啦,这种排序主要应用于数不大的数组中, 例如学习成绩之类的。

代码

使用的是java

说实在的,代码是从这里copy的。写起来比较蛋疼,所以我就没有写,给这个代码中添加了注释。

package hark.sort.distributionsort;

/*
* 珠排序
*/
public class BeadSort {
public static void main(String[] args) {
BeadSort now = new BeadSort();
int[] arr = { 5, 9, 6, 2, 7, 4, 1, 2, 3, 8 };
System.out.print("Unsorted: ");
now.display1D(arr); int[] sort = now.beadSort(arr);
System.out.print("Sorted: ");
now.display1D(sort);
} int[] beadSort(int[] arr) {
// 寻找数组最大值
int max = 0;
for (int i = 0; i < arr.length; i++)
if (arr[i] > max)
max = arr[i]; // 创建空的排序数组
// 即将grid中所有元素设为_
// 将levelcount所有元素设为0
char[][] grid = new char[arr.length][max];
int[] levelcount = new int[max];
for (int i = 0; i < max; i++) {
levelcount[i] = 0;
for (int j = 0; j < arr.length; j++)
grid[j][i] = '_';
} // 珠排序的核心其实在这段代码,比较巧妙
// 其实大家把值代入试一下就有感觉了
// 注意一下levelcount这个数组,这个数组用来存储多维数组grid中,*的最小索引
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
for (int j = 0; num > 0; j++) {
grid[levelcount[j]++][j] = '*';
num--;
}
}
System.out.println();
display2D(grid); //在这里对于二维数组进行统计(计算*的数量)。 *的数量,即是当前索引数字的大小
int[] sorted = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
int putt = 0;
for (int j = 0; j < max && grid[arr.length - 1 - i][j] == '*'; j++)
putt++;
sorted[i] = putt;
} return sorted;
} void display1D(int[] arr) {
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
System.out.println();
} void display1D(char[] arr) {
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
System.out.println();
} void display2D(char[][] arr) {
for (int i = 0; i < arr.length; i++)
display1D(arr[i]);
System.out.println();
}
}

时间复杂度和空间复杂度都是O(n*m) ,n是数组大小,m是最大值大小。   当然啦,m其实是可以省掉的,省掉就是O(n)啦

参考

http://rosettacode.org/wiki/Sorting_algorithms/Bead_sort#Java

http://www.cnblogs.com/kkun/archive/2011/11/23/2260301.html

---恢复内容结束---

Hark的数据结构与算法练习之珠排序的更多相关文章

  1. Hark的数据结构与算法练习之锦标赛排序

    算法说明 锦标赛排序是选择排序的一种. 实际上堆排序是锦标赛排序的优化版本,它们时间复杂度都是O(nlog2n),不同之处是堆排序的空间复杂度(O(1))远远低于锦标赛的空间复杂度(O(2n-1)) ...

  2. Hark的数据结构与算法练习之圈排序

    算法说明 圈排序是选择排序的一种.其实感觉和快排有一点点像,但根本不同之处就是丫的移动的是当前数字,而不像快排一样移动的是其它数字.根据比较移动到不需要移动时,就代表一圈结束.最终要进行n-1圈的比较 ...

  3. Hark的数据结构与算法练习之Bogo排序

    算法说明 Bogo排序是交换排序的一种,它是一种随机排序,也是一种没有使用意义的排序,同样也是一种我觉得很好玩的排序. 举个形象的例子,你手头有一副乱序的扑克牌,然后往天上不停的扔,那么有一定机率会变 ...

  4. Hark的数据结构与算法练习之梳排序

    算法说明梳排序是交换排序的一种,它其实也是改自冒泡排序,不同之处是冒泡排序的比较步长恒定为1,而梳排序的比较步长是变化的. 步长需要循环以数组长度除以1.3,到最后大于等于1即可. 光说可能比较抽象, ...

  5. Hark的数据结构与算法练习之奇偶排序

    算法说明 奇偶排序又叫奇偶换位排序,砖排序.它是一种交换排序,也是冒泡的一个变种 顾名思义,奇偶排序,其实就是先循环奇数位,然后将奇数位与偶数位比较计算. 然后再循环偶数位,再和奇数位比较运算.看一下 ...

  6. Hark的数据结构与算法练习之鸡尾酒排序

    算法说明 鸡尾酒排序又叫定向冒泡排序,鸡尾酒搅拌排序,搅拌排序,涟漪排序,回来排序,快乐小时排序. 鸡尾酒排序是交换排序的一种,它是冒泡排序的一个轻微的变种.冒泡是从低向高比较排序,鸡尾酒从低向高,从 ...

  7. Hark的数据结构与算法练习之煎饼排序

    算法说明 假设煎锅里边有N个煎饼摞在了一起,它们大小不一并且顺序不一致,我们需要通过拿铲子将它们不停的翻个,进行排序,最终得到一个底下是大的煎饼,上边是小的煎饼的序列.这个排序的过程就是煎饼排序. 这 ...

  8. Hark的数据结构与算法练习之图书馆排序

    算法说明 图书馆排序是插入排序的变种,典型的以空间换时间的一种方法.我个人感觉这种思路可以学习借鉴,但直接使用的场景应该不大. 我们知道,真正的插入排序通常往前边插入元素后,我们要把后边所有的元素后移 ...

  9. Hark的数据结构与算法练习之耐心排序

    算法说明 耐心排序是插入排序的一种,至少wikipedia是这么分的. 话说我明白这个算法的实现思路了,但是不明白这么做的意义何在? 如果明白的朋友帮忙留个言说一下,以后如果我明白的话,我会来修改这个 ...

随机推荐

  1. matlab 之cov 协方差

    COV 1.cov(x) 如果x为向量,返回x的方差 计算方法为: S为方差. 2.cov(X) 如果X为矩阵,把矩阵X的行作为观察值,把列作为变量,返回X的协方差矩阵: diag(cov(X))是每 ...

  2. OCJP-试题集合 | 对象的比较

    Boolean b1 = new Boolean(true); Boolean b2 = new Boolean(true); 下面哪个能得到true的结果: A b1 == b2 B b1.equa ...

  3. 淘宝(阿里百川)手机客户端开发日记第七篇 Service,Handler和Thread

    现在我们已经已经知道android有Service,Handler和Thread这些内容了,但是我想应该还有很多人对此并不是很清楚他们之间的区别! (1)Service 是运行在后端的程序,不与UI直 ...

  4. [Effective JavaScript 笔记] 第14条:当心命名函数表达式笨拙的作用域

    js函数会根据上下文改变其含义. function double(x){return x*2;} 这是一个函数声明,也可以是一个命名函数表达式(named function expression),取 ...

  5. ubuntu硬盘安装卡在探测文件系统

    在硬盘安装ubuntu的时候,会出现这样的问题:安装程序一直卡在正在探测文件系统就不动了.解决的方法很简单.在安装之前要在终端输入sudo空格umount空格 -l空格 /isodevice 不能少一 ...

  6. php友好格式化时间

    php格式化时间显示 function toTime($time) {//$time必须为时间戳 $rtime = date("Y-m-d H:i",$time); $htime ...

  7. django template中load的作用

    某些应用提供自定义标签和过滤器库. 要在一个模板中访问它们, 使用 {% load %} 标签: {% load comments %} {% comment_form for blogs.entri ...

  8. mysql中的unsigned

    unsigned   既为非负数,用此类型可以增加数据长度! 例如如果    tinyint最大是127,那    tinyint    unsigned    最大   就可以到    127 * ...

  9. vim技巧之快速进入引号删除至右引号前的内容

    参考:http://blog.chinaunix.net/uid-23381466-id-88482.html f'l ct' #fX,X可用任何字符,l表示向右移一位,ct'表示删除至引号前di'

  10. 24.栈的push和pop序列[StackPushPopSequence]

    [题目] 输入两个整数序列.其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序.为了简单起见,我们假设push序列的任意两个整数都是不相等的. 比如输入的push序列是1.2 ...