素数环问题(Java实现)

*文中内容大多来源于《数据结构 --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实现)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值