数据结构作业2-多项式相加、约瑟夫问题

本文探讨了多项式相加的实现,通过链表操作展示了如何合并两个多项式,并结合经典问题约瑟夫环问题,介绍了如何用循环链表进行多次遍历求解。通过实例演示了算法核心和链表操作技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多项式相加

完成函数 public Node add(Node link1, Node link2) 提示:link1 link2 分别为两条链表的头节点(多项式从下一个节点开始,若为空多项式,则仅含头节点) 函数请返回结果多项式的第一个节点,不要返回头节点。注意初始指数的顺序是从小到大。

伪代码:不断比较指数和连接
在这里插入图片描述

//Node定义
public class Node {
    public int coef;//系数  
    public int exp;//指数  
    public Node next=null;//下个节点  
    public Node(){ //默认的初始化
        coef=0;  
        exp=0;  
    }  
    public Node(int coef,int exp){  //定义结点的系数和指数
        this.coef=coef;  
        this.exp=exp;  
    } 
}
public class PolynList {

    //多项式相加实现过程
    public Node add(Node link1, Node link2) {
        Node res = new Node();
        Node p = res;//存一个初始地址,方便返回
        link1 = link1.next;//把头结点略过去
        link2 = link2.next;
        while(link1 != null && link2 != null){
            if(link1.exp == link2.exp){//如果指数相等
                link1.coef += link2.coef;
                if(link1.coef != 0){//如果相加等于0就不加入结果了
                    res.next = link1;
                    res = link1;
                }
                link1 = link1.next;//均要前进
                link2 = link2.next;
            }else if(link1.exp > link2.exp){
                res.next = link2;
                res = link2;
                link2 = link2.next;
            }else {
                res.next = link1;
                res = link1;
                link1 = link1.next;
            }
        }
        //如果有一个为null退出了循环,让另一个的剩余部分接在res后面
        if(link1 != null){
            res.next =link1;
        }else if(link2 != null){
            res.next = link2;
        }else{
            res.next = null;
        }
        return p.next;
   }
}

约瑟夫问题

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

核心算法:循环链表多次遍历
在这里插入图片描述
链表实现:

public class Josephus {
    public static class Node {
        public int num;//号数
        public Node next=null;//下个节点
        public Node(){ //默认的初始化
            num=0;
        }
        public Node(int num){  //定义结点的系数和指数
            this.num=num;
        }
    }

    public static int lastRemaining(int n, int m) {//不要更改这里的static修饰符
        Node nums = new Node();//指向队列链表的尾结点
        Node p = new Node();//准备存报数的数字构成的链表
        Node head = nums;//指向队列链表的头结点
        for(int i = 0; i < n; i++){
            nums.next = new Node(i);
            nums = nums.next;
        }
        nums.next = head.next;//循环链表
        Node rear = head;//一个引用,用于循环遍历数组 开始是头指针

        for(int i = 1; i <= n-1; i++){
           for(int j = 1; j <= m-1; j++)
               rear = rear.next;//1 2
           if(i == 1){
               p = rear.next;//第一个被淘汰的数,可以取等
           }else{
               p.next = rear.next;//为了把报数的数字连起来
               p = rear.next;//指向3
           }
           rear.next = p.next;
        }

        p.next = rear;
        return rear.num;//这里return自己的结果
    }

//    public static void main(String[] args){
//        System.out.println(lastRemaining(5, 3));
//    }

}

数组实现:

ArrayList<Integer> nums = new ArrayList<Integer>();
        for(int i = 0; i < n; i++){
            nums.add(i);
        }
        int p = 1;
        for(int i = 0; nums.size() != 1; i++){
            if(i == nums.size()) i = 0;//遍历完了一次,归零重新遍历
            if(p % m == 0){
                nums.remove(i--);//因为数组位数会减少,i--保证正常地遍历
            }
            p++;//m的倍数会被移除
        }
        return nums.get(0);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值