没有返回值的add递归,老师帮忙看看是否正确?

没有返回值的add递归,老师帮忙看看是否正确?

public void add(LinkedListR listR, int index, E e) {

   if (index < 0 || index > size) {
       throw new IllegalArgumentException("Add failed. Illegal index"); }
   if (index == 0) {
       listR.head=new Node(e,listR.head);
   }  else {
       Node removed = listR.head;
       listR.head=listR.head.next;
       add(listR, index - 1, e);
       removed.next = listR.head;
       listR.head=removed;
   }
   size++;
}


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
liuyubobobo 2022-07-21 03:40:58

是有问题的。


下面的代码的 add 使用了你的逻辑。测试的 main 函数中,你会看到,当最后一个添加操作在 index = 2 的位置添加了 666 以后,原来的链表 index = 2 位置后面的部分丢失了。


即:0->1->2->3->4->null 在 index = 2 添加 666 以后,应该是:

 0->1->666->2->3->4->null


你的逻辑的得到结果是:

 0->1->666->null


另外,你的程序中的 size 也会多次添加,在同样的这份程序中,一共添加了 6 个元素,你的程序最终得到的 size 是 18。


可以自己仔细调试一下,理解一下,为什么会这样?


public class LinkedList<E> {
    
    private class Node{
        public E e;
        public Node next;
        public Node(E e, Node next){
            this.e = e;
            this.next = next;
        }
        public Node(E e){
            this(e, null);
        }
        public Node(){
            this(null, null);
        }
        @Override
        public String toString(){
            return e.toString();
        }
    }
    
    private Node head;
    private int size;
    
    public LinkedList(){
        head = null;
        size = 0;
    }
    
    public void add(LinkedList<E> listR, int index, E e){
        if(index < 0 || index > size)
            throw new IllegalArgumentException("Add failed. Illegal index.");
        if(index == 0)
            listR.head = new Node(e);
        else{
            Node removed = listR.head;
            listR.head=listR.head.next;
            add(listR, index - 1, e);
            removed.next = listR.head;
            listR.head=removed;
        }
        size ++;
    }
    
    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        for(Node cur = head ; cur != null ; cur = cur.next)
            res.append(cur + "->");
        res.append("NULL");
        return res.toString();
    }
    
    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        for(int i = 0 ; i < 5 ; i ++){
            linkedList.add(linkedList, i, i);
            System.out.println(linkedList);
        }
        linkedList.add(linkedList, 2, 666);
        System.out.println(linkedList); // 这个输出是错的
        
        System.out.println(linkedList.size); // 这个输出也是错的
    }
}


继续加油!:)

  • 提问者 飞飞侠91 #1

    老师您好,1、第34行应该是listR.head=new Node(e,listR.head);

    2、size++不能放在递归函数内,好像放到递归函数哪里都不行,只能够另外使用函数调用递归函数,然后再size++;

    谢谢老师!

    2022-07-21 21:58:42
  • liuyubobobo 回复 提问者 飞飞侠91 #2

    第一个问题是我“转移”你的代码的时候出的错误,抱歉。

    第二个问题,size 只要跟着 new 就好。因为 new 一个新的 Node 的时候,才是真正的添加一个节点的时候。所以这个代码是正确的:


    ```

        public void add(LinkedList<E> listR, int index, E e){

            if(index < 0 || index > size)

                throw new IllegalArgumentException("Add failed. Illegal index.");

            if(index == 0){

                listR.head = new Node(e, listR.head);

                size ++;

            }

            else{

                Node removed = listR.head;

                listR.head=listR.head.next;

                add(listR, index - 1, e);

                removed.next = listR.head;

                listR.head=removed;

            }

        }

    ```


    不过这样只是逻辑正确了,在我看来这个函数接口设计的怪怪的。在调用添加一个元素的时候,需要:linkedList.add(linkedList, 2, 666); 本身就是对 linkedList 做调用,第一个参数还要把 linkedList 传进去。可以思考一下能不能不这样做?当然,如果只是追求逻辑正确,到这里就可以了。相信通过这个练习,你对递归的理解更深刻了:)


    继续加油!:)

    2022-07-21 23:43:24
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
算法与数据结构
  • 参与学习       2583    人
  • 解答问题       1082    个

慕课网算法名师Liuyubobobo,5年集大成之作 从0到工作5年,算法与数据结构系统解决方案

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师