珠排序详解java实现

珠排序的原理如图:

定义和图片引用详见排序算法详解(Java实现 + 动画演示)_javagui排序算法动画-CSDN博客

代码实现如下:

package org.xxxxx.modules.util;

import lombok.Data;

import java.util.*;

public class PearlTest {


    public static void main(String[] args) {
        List<Integer> randomVauleList = RandomIntegerUtils.getRandomIntegers(0, 100, 10);
        long st = System.currentTimeMillis();
        PearlSort result = new PearlSort(randomVauleList);
        System.out.println(result.rawList);
        System.out.println(result.sortList);
        System.out.println(System.currentTimeMillis() - st);
    }

    @Data
    private static final class PearlSort {
        /**
         * 珠盘
         */
        private final List<LinkedList<Integer>> abacus = new LinkedList<>();
        /**
         * 原数字顺序
         */
        private final List<Integer> rawList;
        /**
         * 排序后的顺序
         */
        private final List<Integer> sortList;

        public PearlSort(List<Integer> rawList) {
            this.rawList = rawList;
            this.sortList = new ArrayList<>();
            this.rawList.removeIf(Objects::isNull);
            for (Integer value : this.rawList) {
                //添加珠子到珠盘并坠落
                addPearl(value);
            }
            //统计珠盘的珠子
            pearlFall(sortList);
        }

        private void pearlFall(List<Integer> sortList) {
            while (abacus.size() > 0){
                int value = 0;
                for (LinkedList<Integer> bunch : abacus) {
                    if (bunch.size() > 0){
                        bunch.removeFirst();
                        value++;
                    }
                }
                abacus.removeIf(AbstractCollection::isEmpty);
                sortList.add(value);
            }
        }

        private void addPearl(Integer value) {
            autoSizeByValue(value);
            for (int i = 0; i < value; i++) {
                List<Integer> bunch = abacus.get(i);
                bunch.add(0);
            }
        }

        private void autoSizeByValue(Integer value) {
            int increment = value - abacus.size();
            if (increment > 0){
                for (int i = 0; i < increment; i++) {
                    abacus.add(new LinkedList<>());
                }
            }
        }
    }
}

其中工具类RandomIntegerUtils实现详见猴子排序详解-CSDN博客

运行结果如下:

可以看出珠排序的算法时间复杂度和空间复杂度不仅和排序数字的个数n有关,还和排序数字的最大值vmax大小有关,有文章认为其时间复杂度是O(n), 实际运行却慢的多,这是因为没有考虑排序不仅要移动珠子,创建珠子将珠子放到珠盘也需要时间,所以时间复杂度必然和vmax有关。

分别添加2000,20000,200000,测试结果如下:

从结果中可以看出时间增长十分明显,但又不能用简单的vmax或者vmax的平方来描述它们的关系。总而言之这是一个仅在数字个数100以内,数字大小不超过10000时还可以一用的算法,不过如果你的电脑是某星文明的量子计算机,运算无限快,空间无限大,就算最大值是一个小目标应该也没有什么问题。

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值