怎么创建基本有序、部分无序的数组

怎么创建基本有序、部分无序的数组

基本思路

利用桶排序,桶与桶之间是有序排列的,桶内是无序的。先随机产生长度为n的数组,再创建一个小于n的数组(这里为 1 2 n \frac{1}{2}n 21n,增大冲突概率)用于安放排序后的数,最后将数对号入座。

输入是 X i ( 0 , 1 , 2 , . . . , n − 1 ) X_i(0,1,2,...,n-1) Xi(0,1,2,...,n1),关键字经函数 K ( x i ) K(x_i) K(xi)在区间 [ 0 , 1 ) [0,1) [0,1)左闭右开上分布

输出是 Y i ( 0 , 1 , 2 , . . . , n − 1 ) Y_i(0,1,2,...,n-1) Yi(0,1,2,...,n1) 其中对大部分 i , j i,j i,j Y i &lt; Y j Y_i&lt;Y_j Yi<Yj

变量是 P i ( 0 , 1 , . . . , 1 2 n ) P_i(0,1,...,\frac{1}{2}n) Pi(0,1,...,21n)为桶

伪代码

for i = 0 to n-1 do:
    k=K(Xi)
    b=[k*N]
    将Xi插入链表Pb中
for b = 1 to N-1 do:
    将链表Pb连接到链表Pb-1后
依据合并后的链表,将X中的记录依次拷贝到Y中

算法实现

import java.util.Arrays;
import java.util.Random;
import java.util.stream.Stream;

/**
 * @创建人 skiner
 * @创建时间 2018/12/6
 * @描述
 */
class PartialSortData {

    /**
     * 用于生成随机数据
     *
     * @param length
     * @return
     */
    public static int[] getRandomData(int length) {
        Random random = new Random();
        return Stream.generate(() -> random.nextInt())
                .limit(length)
                .mapToInt(Integer::valueOf)
                .toArray();
    }

    public static int[] getData(int length) {
        int halfLength = length / 2;
        //随机数组
        int[] X = getRandomData(length);
        int[] Y = new int[length];
        //桶节点
        LinkedNode[] S = new LinkedNode[halfLength];
        //找最大和最小值,用于标准化
        int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
        for (int i = 0; i < length; i++) {
            max = max < X[i] ? X[i] : max;
            min = min > X[i] ? X[i] : min;
        }

        for (int i = 0; i < length; i++) {
            //转成double防止溢出成负数
            double k = (((double) X[i] - min) / ((double) max - min)) * 0.5;

            int b = (int) (k * length);
            if (b == halfLength) {
                b--;
            }
            if (S[b] == null) {
                S[b] = new LinkedNode(X[i], null);
            } else {//头插法
                LinkedNode t = new LinkedNode(X[i], S[b]);
                S[b] = t;
            }
        }

        int index = 0;
        //收集数据
        for (int i = 0; i < halfLength; i++) {
            if (S[i] != null) {
                LinkedNode t = S[i];
                while (t != null) {
                    Y[index++] = t.data;
                    t = t.next;
                }
            }
        }
        return Y;
    }

    /**
     * 自定义链表节点
     */
    static class LinkedNode {
        int data;
        LinkedNode next;

        LinkedNode() {
        }

        LinkedNode(int data, LinkedNode next) {
            this.data = data;
            this.next = next;
        }

    }

    public static void main(String[] args) {
        int[] data = getData(100);
        Arrays.stream(data).forEach(x -> System.out.print(x + " "));
    }
}

输出数据

-2127179259 -2005903801 -1039159461 -1107165137 -650349811 -518757568 -545528620 360087035 774034788 699767372 689395581 846318036 970609168 1040444717 875890217 1623872638 1309046808 1441476071 1576228130 1432574300

参考文献

《基于数组的桶排序算法》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值