You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现带Scanner输入的循环单链表插入元素覆盖问题排查

循环单链表插入异常问题排查

问题现象

本次作业要求实现循环单链表的节点插入方法,通过Scanner获取用户输入。当前输入3个元素时功能正常,但插入第4个元素时出现异常:
依次输入1、2、3后再插入新元素4,列表展示结果为1、2、4,期望结果应为1、2、3、4,第3个元素被覆盖。

问题代码

主方法代码

import java.util.Scanner;

public class MySinglyLinkedCircularListMain {
    public static void main(String[] args) throws ListOverflowException {
        Scanner keyboard = new Scanner(System.in);

        MySinglyLinkedCircularList<Node> singlyLinkedCircularList = new MySinglyLinkedCircularList<>();

        while (true) {
            System.out.println("+---------------------------------------------------+");
            System.out.println("| Select the Number to be executed:                 |\n" +
                    "| 1) Insert an element                              |\n" +
                    "| 2) Delete an element from the list                |\n" +
                    "| 3) Get an element from the list                   |\n" +
                    "| 4) Search an element in the list                  |\n" +
                    "| 5) Number of elements in the list                 |\n" +
                    "| 6) Show the elements in the list                  |");
            System.out.print("+---------------------------------------------------+ \n");
            System.out.print("Input your choice: ");
            int intInput = keyboard.nextInt();

            if (intInput == 1) {
                singlyLinkedCircularList.insert(new Node(singlyLinkedCircularList));

            } else if (intInput == 2) {
                singlyLinkedCircularList.delete(new Node(singlyLinkedCircularList));
             

            } else if (intInput == 3) {
                singlyLinkedCircularList.getElement(new Node(singlyLinkedCircularList));

            } else if (intInput == 4) {
                singlyLinkedCircularList.search(new Node(singlyLinkedCircularList));

            } else if (intInput == 5){
                System.out.println("The current capacity of the single circular linked list is "
                        + singlyLinkedCircularList.getSize());

            } else if (intInput == 6) {
                singlyLinkedCircularList.showAllElements();
                System.out.println();
            }
        }
    }
}

Node类代码

public class Node<T> {
    T data;
    Node<T> next;

    public Node(T data) {
        this.data = data;
        next = null;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public void setNext(Node<T> node) {
        next = node;
    }

    public Node<T> getNext() {
        return next;
    }
}

链表实现类(含插入方法)代码

import java.util.NoSuchElementException;
import java.util.Scanner;

public class MySinglyLinkedCircularList<E> implements MyList<E> {
    Scanner keyboard = new Scanner(System.in);
    int size;
    Node<E> startNode;
    Node<E> endNode;

    public MySinglyLinkedCircularList() {
        size = 0;
        startNode = endNode = null;
    }

    public int getSize() {
        return size;
    }

    public void insert(E data) throws ListOverflowException {
        System.out.print("Input the element you want: ");
        data = (E) keyboard.next();

        Node<E> newNode = new Node(data);


        if (startNode == null) {
            startNode = endNode = newNode;
            startNode.next = startNode;
            size++;
            System.out.println("Element " + startNode.getData() + " has been stored in position "
                    + getSize() + " and is now referenced itself");

        } else {
            Node<E> addNode = endNode;

            for (int i = 0; i < getSize(); i++) {
                addNode = addNode.getNext();
            }
            addNode.next = newNode;
            newNode.next = startNode;
            size++;
}
}

元素展示方法代码

public void showAllElements() {
        Node<E> showNode = startNode;
        int i = 0;

        System.out.print("Here are the current elements: ");
        while (i<getSize()) {
            System.out.print(showNode.getData() + " ");
            showNode = showNode.getNext();
            i++;
        }
        System.out.print(showNode.getData());
    }

自定义List接口代码

public interface MyList<E> {
    public int getSize();
    public void insert(E data) throws ListOverflowException;
    public E getElement(E data) throws NoSuchElementException; 
    public boolean delete(E data); // returns false if the data is not deleted in the list
    public boolean search(E data);
    public void showAllElements();
}

根因分析

  1. 插入逻辑错误:代码已经维护了endNode尾节点指针,但插入尾部后没有更新endNode为新插入的节点,同时多余的循环逻辑导致后续插入时总是覆盖旧的尾节点后继,造成节点丢失。
  2. 展示逻辑错误:while循环已经遍历输出了所有size个节点,最后额外多输出一次节点值,此时指针已经回到首节点,会导致输出结果冗余。
  3. 泛型使用错误:主类中声明的链表泛型为Node类型,实际存储的是用户输入的字符串,类型不匹配,且insert方法内部直接覆盖了传入的参数,参数设计不合理。

修复方案

1. 修正插入逻辑

删除多余的循环,插入后更新尾节点指针:

public void insert(E data) throws ListOverflowException {
    System.out.print("Input the element you want: ");
    data = (E) keyboard.next();
    Node<E> newNode = new Node(data);
    if (startNode == null) {
        startNode = endNode = newNode;
        startNode.next = startNode;
        size++;
        System.out.println("Element " + startNode.getData() + " has been stored in position "
                + getSize() + " and is now referenced itself");
    } else {
        // 直接在尾节点后插入新节点
        endNode.next = newNode;
        newNode.next = startNode;
        // 更新尾节点为新插入的节点
        endNode = newNode;
        size++;
    }
}

2. 修正展示逻辑

删除多余的输出语句:

public void showAllElements() {
    Node<E> showNode = startNode;
    int i = 0;
    System.out.print("Here are the current elements: ");
    while (i<getSize()) {
        System.out.print(showNode.getData() + " ");
        showNode = showNode.getNext();
        i++;
    }
}

3. 修正主类泛型与调用逻辑

调整泛型为实际存储的String类型:

// 泛型改为存储String
MySinglyLinkedCircularList<String> singlyLinkedCircularList = new MySinglyLinkedCircularList<>();
// 调用insert时无需传入Node对象
if (intInput == 1) {
    singlyLinkedCircularList.insert(null);
}

如果要代码更合理,可直接删除insert方法的入参,因为方法内部没有使用传入的参数,完全通过Scanner读取输入。


内容的提问来源于stack exchange,提问作者Julliard - Kun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:48:00