*文中内容大多来源于《数据结构 --Java语言描述》(第二版) 刘小晶 杜选 主编
*此系列文章作为学习记录,若文中内容有误,请大家指出,谢谢
/**
* 问题:将1 ~ n的n个自然数排列成环形,使得每相邻两数之和为素数,从而构成一个素数环。
* 解决思路:
* (1)先引入顺序表类SqList和链队列类LinkQueue,再创建SqList类的一个对象L作为顺序表,用于存放素数环的数据元素;
* 创建LinkQueue类的一个对象Q,作为队列用于存放还未加入到素数环中的自然数。
* (2)初始化顺序表L和队列Q:将1加入到顺序表L中,将2 ~ n的自然数全部加入到Q队列中。
* (3)将出队的队首元素p与素数环最后一个数据元素q相加,若两数之和是素数并且p不是队列中的最后一个数据元素(或
* 队尾元素),则将p加入到素数环中;否则说明p暂时无法处理,必须再次入队等待,再重复此过程。若p为队尾元素,则还
* 需要判断它与素数环的第一个数据元素相加的和数是否为素数,若是素数,则将p加入到素数环,求解结束;若不是素数,
* 则重复(3),直到队列为空或已对队列中每一个数据元素都遍历了一次且未能加入到素数环为止。
*/
import Book_U2.SqList;
public class Example3_5 {
//判断正整数是否为素数
public boolean isPrime(int num){
if (num == 1) //整数1返回false
return false;
Double n = Math.sqrt(num); //求平方根
for (int i = 2; i <= n.intValue(); i++){
if (num % i == 0) //模为0返回false
return false;
}
return true;
}
//求n个正整数的素数环,并以顺序表返回
public SqList makePrimeRing(int n) throws Exception{
if (n % 2 != 0) //n为奇数则素数环不存在
throw new Exception("素数环不存在!");
SqList L = new SqList(n); //构造一个顺序表
L.insert(0, 1); //初始化顺序表的首结点为1
LinkQueue Q = new LinkQueue(); //构造一个链队列
for (int i = 2; i <= n; i++) //初始化链队列
Q.offer(i);
return insertRing(L, Q, 2, n); //返回素数环
}
/**
* 在一个顺序表中插入第m个数,使其与顺序表中第m - 1个数的和为素数,若m等于n,
* 则还要满足第m个数与1的和也为素数,程序返回顺序表
*/
public SqList insertRing(SqList L, LinkQueue Q, int m, int n) throws NumberFormatException,Exception{
int count = 0; //记录遍历队列中的数据元素的个数,防止在一次循环中重复遍历
while(!Q.isEmpty() && count <= n - m){ //队列非空,其未重复遍历队列
int p = (Integer)Q.poll();
int q = (Integer)L.get(L.length() - 1);
if (m == n){
if (isPrime(p + q) && isPrime(p + 1)) {
L.insert(L.length(),p);
return L;
}
else
Q.offer(p);
}
else if (isPrime(p + q)){
L.insert(L.length(),p);
if (insertRing(L, Q, m + 1, n) != null)
return L;
L.remove(L.length() - 1);
Q.offer(p);
}
else
Q.offer(p);
++count;
}
return null;
}
public static void main(String[] args) throws Exception{
Example3_5 r = new Example3_5();
SqList L = r.makePrimeRing(6);
for (int i = 0; i < L.length(); i++)
System.out.print(L.get(i) + " ");
}
}
关于SqList的代码请移步至数据结构_线性表_顺序表(Java实现)