怎么创建基本有序、部分无序的数组
基本思路
利用桶排序,桶与桶之间是有序排列的,桶内是无序的。先随机产生长度为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,...,n−1),关键字经函数 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,...,n−1) 其中对大部分 i , j i,j i,j, Y i < Y j Y_i<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