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

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

基本思路

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

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

输出是Yi(0,1,2,...,n1)Y_i(0,1,2,...,n-1) 其中对大部分i,ji,jYi<YjY_i<Y_j

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

伪代码

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

参考文献

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

posted @ 2018-12-07 21:31  mengfu188  阅读(187)  评论(0)    收藏  举报