队列求解素数筛

版权声明: https://blog.csdn.net/King8611/article/details/82932270

这是我们数据结构的作业,先看要求吧:

编程实现队列类,要求包括基本变量和基本操作,也没啥。

队列中两个变量,头节点和尾节点。每个节点不仅要有next节点值,还要有last节点。

然后insert函数和pop函数,一个插入一个删除。不过这个要分几种情况,当队列为空,或者只有一个元素。

队列实现:

class Link<T>{	
	Node<T> head;									//队列头节点
	Node<T> tail;									//队列尾节点
	public void insert(T x) {						//插入函数
		Node<T> t=new Node<T>(x);
		if(head==null) {			//如果队列为空
			head=t;
			tail=t;
		}
		else if(head==tail) {		//如果队列只有一个元素
			tail=t;
			tail.last=head;
			head.next=tail;
		}
		else {						//其他情况
			tail.next=t;
			t.last=tail;
			tail=t;
		}
	}
	public T getFront() {							//得到头节点
		return head.v;
	}
	public T pop() {								//删除头节点,三种情况,分类处理
		T t=head.v;
		if(head==null) {
			return null;
		}
		if(head==tail) {
			head=tail=null;
			return t;
		}
		head=head.next;
		head.last=null;
		return t;
	}
	public boolean isEmpty() {						//判断是否为空
		return head==null;
	}
	private class Node<T>{
		Node<T> next;			//上一个节点
		Node<T> last;			//下一个节点
		T v;					//权值
		public Node(T x){
			this.v=x;
		}
		public Node() {}
	}
}

下面是实现素数环,原理我也不知道。

就是用一个顺序表,一个队列。

顺序表Q先add(1),队列L add(2-n);

然后下面操作重复:

1、取L首

2、看是否和Q尾和构成素数

3、如果是,插入Q尾,如果否入队L,重复1直到队列为空。

原理其实我也不清楚。不过好像就是能用。

然后加个区间筛优化一下判断素数。

public class Main {
	static StreamTokenizer in=new StreamTokenizer (new BufferedReader(new InputStreamReader(System.in)));
    static boolean isPrime[];
    static int isP_Len=100;
    public static void main(String[] args) throws Exception {
    	int arr[]=getPrimeRing(20);
    	for(int i=0;i<20;i++) {
    		System.out.println(arr[i]);
    	}
    }
    ///==========================================得到素数环主函数
    /*
     * 我真的不知道为啥要用队列实现素数环,也不知道原理,为啥是这样。
     * 而且写起来又这么复杂。
     * bfs写起来那么简便。
     * 这个时间复杂度不好算,也不知道那个复杂度高。
     * 结果环用数组存储
     */
    static int[] getPrimeRing(int n) {
    	int arr[]=new int[n];
    	getPrimeArrays();
    	Link<Integer> list=new Link<Integer>();
    	arr[0]=1;
    	int len=1;
    	for(int i=2;i<=n;i++) {
    		list.insert(i);
    	}
    	while(!list.isEmpty()) {
    		int t=list.pop();
    		if(isP(t+arr[len-1])) {
    			arr[len++]=t;
    		}
    		else {
    			list.insert(t);
    		}
    	}
    	return arr;
    }
    //=============================================
    static boolean isP(int x) {
    	return isPrime[x];
    }
    //筛法求素数,复杂度会低很多。n^3/2到几乎线性的辅助度。
    static void getPrimeArrays() {
    	isPrime=new boolean[isP_Len];
    	for(int i=2;i<isP_Len;i++) {
    		isPrime[i]=true;
    	}
    	for(int i=2;i<isP_Len;i++) {
    		if(isPrime[i]) {
    			for(int j=i*2;j<isP_Len;j+=i) {
    				isPrime[j]=false;
    			}
    		}
    	}
    }
    static int getInt() throws Exception{
    	in.nextToken();
    	return (int)in.nval;
    	
    }
}

猜你喜欢

转载自blog.csdn.net/King8611/article/details/82932270