适用于对内存要求有严格规范,并且速度不能太低的情况
import java.util.Scanner;
import java.util.Vector;
/**
* @Classname VectorBit
* @Description 使用逻辑运算实现位向量,来实现位排序,一个int 类型可以存储8个数的是否存在
* 这只适用于没有数值重复
* 实现细节:
* 1:将每个位置变为0
* 2:将每个输入数对应位置输入1
* 3:从0-n位遍历看是否为1,如果为1输出这个值
* 空间复杂度:10000000(bit)=10000000/1000/1000/8=1.25MB
* @Date 2019/3/27 19:42
* @Created by 大大
*/
public class VectorBit {
private final int BitWords=32;//因为一个int,32位
private int Num=10000000;//表示1000万个整数
private final int shift=5;//x>>5==x/32
private final int mask =0x1F; //掩码11111=31 ,x&mask 取值在0-31之间,其余位变0后就是x%32的结果
int []array;//因为普通除法向下取余,只初始化一次因此就不移位了
public VectorBit(){
array=new int[1+Num/BitWords];
}
public VectorBit(int N){
this.Num=N;
array=new int[1+Num/BitWords];
}
/**
*将某个值对应的位数作为1
*/
public void set(int number){
array[number>>shift] =array[number>>shift]|(1<<(number&mask));
}
/**
* 验证某个值是否位于数组
*/
public boolean test(int number){
return ((array[number>>shift]&(1<<(number&mask)))>0)?true:false;
}
/**
* 清除某一位*/
public int clc(int number){
return array[number>>shift]& ~(1<<(number&mask));
}
public static void main(String[] args) {
VectorBit vectorBit=new VectorBit();
StringBuilder builder=new StringBuilder();
Scanner in =new Scanner(System.in);
int temp;
while(!in.hasNext("#")){
temp=in.nextInt();
vectorBit.set(temp);
builder.append(temp+" ");
}
System.out.println(builder);
for (int i = 0; i < vectorBit.Num; i++)
if (vectorBit.test(i))
System.out.print(i+" ");
}
}
随机产生一个不重复的随机数组
package Algorith.编程珠玑.第一章位排序;
import java.util.Arrays;
import java.util.Random;
/**
* @Classname 随机整数
* @Description 生成0-n-1中 k个随机顺序的随机整数
* @Date 2019/3/27 20:43
* @Created by 大大
*/
public class 随机整数4 {
public static int[] randomArray(int n,int k){
Random random=new Random();
int []array=new int[k];
int index=0;
while(index<k){
int temp=random.nextInt(n);
boolean repeat=false;
for (int i=0;i<index;i++){
if (array[i]==temp){
repeat=true;
break;
}
}
if(!repeat){
array[index]=temp;
++index;
}
}
return array;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(随机整数4.randomArray(10000000,10)));
}
}
若内存有严格限定则需要多次归并排序
package Algorith.编程珠玑.第一章位排序;
import Algorith.ArrayAndString.排序算法;
import java.util.Arrays;
/**
* @Classname VexctorBit5
* @Description 内存有限制只能是1MB但,之前算法却需要1.25MB则么办呢,就需要,
* 分波进行排序,比如分两拨,第一次排0-5000000,第二次次排501-10000000
* 根据内存限制动态决定要分几次排序
* @Date 2019/3/27 21:19
* @Created by 大大
*/
public class VexctorBit5 {
public static void main(String[] args) {
int k=1000000;
int []array=随机整数4.randomArray(10000000,k);
long s=System.currentTimeMillis();
VectorBit vectorBit=new VectorBit(5000000);
for (int i=0;i<k;i++){
if(array[i]<5000000){
vectorBit.set(array[i]);
}
}
for (int i=0;i<5000000;i++){
if(vectorBit.test(i)){
System.out.println(i+" ");
vectorBit.set(i);
}
}
for (int i=0;i<k;i++){
if(array[i]>5000000){
vectorBit.set(array[i]-5000000);
}
}
for (int i=0;i<5000000;i++){
if(vectorBit.test(i)){
System.out.println(i+5000000+" ");
vectorBit.set(i);
}
}
long end=System.currentTimeMillis();
System.out.println("位排序用时:"+(end-s));
s=System.currentTimeMillis();
排序算法.mergeSort(array,0,k-1);
end=System.currentTimeMillis();
System.out.println("快排用时:"+(end-s));
}
}