Java队列递归求解素数环问题

思路:

1.创建顺序表SqList的对象L,用于存放素数环中的数据元素;

创建链队列LinkQueue对象Q,用于存放还未加入到素数环中的元素。


2.初始化顺序表L和队列Q:将1加入到顺序表L中,将2~n的自然数全部加到Q队列中。


3.递归,将出队的队首元素p与素数环最后一个数据元素q相加,

若两数之和是素数而且p不是队尾元素,则将p加入到素数环中;

否则说明p暂时无法处理,必须再入队等待,重复此过程。

若p为队尾元素,则还需要判断它与素数环的第一个数据元素的和是否未素数,

若是素数,则将p加入到素数环,求解结束;若不是素数,则重复3,

直到队列为空或者已对队列中每一个数据元素都遍历了一次且未能加入到素数环为止。


实现:用到了之前写的顺序表和链队列

package queueTest;

import linearList.SqList;

public class PrimeRing {

	public boolean isPrime(int num) {
		// 判断是否为素数
		if (num == 1) {
			return false;
		}

		Double n = Math.sqrt(num);// 减小运算量
		for (int i = 2; i <= n.intValue(); i++) {
			if (num % i == 0) {
				return false;
			}
		}
		return true;
	}

	public SqList insertRing(SqList L, LinkQueue Q, int index, int total) throws NumberFormatException, Exception {
		// 在一个顺序表L中插入第index个数,使之与顺序表中第index-1个数的和为素数,
		// 若index等于total,则还需满足第index个数与1的和也为素数,程序返回顺序表
		int count = 0;// 记录遍历队列中数据元素的个数,防止在一次循环中重复遍历
		while (!Q.isEmpty() && count <= total - index) {
			int p = (Integer) Q.poll();// 取队列第一个元素
			int q = (Integer) L.get(L.length() - 1);// 取顺序表最后一个元素
			if (index == total) {// 如果是最后一个元素
				if (isPrime(p + q) && isPrime(p + 1)) {// 而且与顺序表最后一个元素,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, index+1, total) != null) {// 递归
					return L;
				}
				L.remove(L.length()-1);// 移除顺序表表尾数据元素
				Q.offer(p);
			} else {
				Q.offer(p);
			}
			++count;
		}
		return null;
	}
	
	public SqList makePrimeRing(int n)throws Exception{
		//求n个正整数的素数环,并以顺序表返回
		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);
	}

	public static void main(String[] args) throws Exception {
		PrimeRing pr=new PrimeRing();
		SqList L=pr.makePrimeRing(8);
		for(int i=0;i<L.length();i++){
			System.out.print(L.get(i)+" ");
		}
	}

}

输出示例:

1 2 3 8 5 6 7 4 


  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值