佇列求解素數篩
阿新 • • 發佈:2018-11-11
這是我們資料結構的作業,先看要求吧:
程式設計實現佇列類,要求包括基本變數和基本操作,也沒啥。
佇列中兩個變數,頭節點和尾節點。每個節點不僅要有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; } }