java中的Insert()节点方法?

java中的Insert()节点方法?,java,linked-list,Java,Linked List,我有一个LinkedList,它是我在创建乐队、歌曲和歌曲列表时创建的 示例输出: 乐队:Led Zepplen |歌曲:通往天堂的阶梯|持续时间:8.02分钟 乐队:AC/DC |歌曲:黑色回归|持续时间:4.14分钟 乐队:滚石乐队|歌曲:把它涂成黑色|持续时间:3.46分钟 我不明白的是如何实现一个方法,在这个方法中,我可以在任何给定的位置插入一个节点。到目前为止,我的代码如下所示: public class Song { private String band; priv

我有一个LinkedList,它是我在创建乐队、歌曲和歌曲列表时创建的

示例输出:

乐队:Led Zepplen |歌曲:通往天堂的阶梯|持续时间:8.02分钟
乐队:AC/DC |歌曲:黑色回归|持续时间:4.14分钟
乐队:滚石乐队|歌曲:把它涂成黑色|持续时间:3.46分钟

我不明白的是如何实现一个方法,在这个方法中,我可以在任何给定的位置插入一个节点。到目前为止,我的代码如下所示:

public class Song {
    private String band;
    private String name;
    private double duration;
    Song next;
    
    public Song(String band, String name, double duration) {
        this.band = band;
        this.name = name;
        this.duration = duration;
    }

    public String getBand() {
        return band;
    }

    public void setBand(String band) {
        this.band = band;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getDuration() {
        return duration;
    }

    public void setDuration(double duration) {
        this.duration = duration;
    }

    public Song getNext() {
        return next;
    }

    public void setNext(Song next) {
        this.next = next;
    }
    
    public Song getLastNode() {
        Song currentNode = this;
        while(currentNode.next != null) {
            currentNode = currentNode.next;
        };
        return currentNode;
    }
        
    public void append(Song newSong) {
        Song tmpNode = this.getLastNode();
        tmpNode.next = newSong;
    }
    
    public void printAllSongs() {
        // print all songs from j
        Song currentNode = this;
        do {
            System.out.println("Band: " + currentNode.getBand() + " | " +  
                                " Song: " + currentNode.getName() +  " | " + 
                                " Duration: " + currentNode.getDuration() + " minutes");
            currentNode = currentNode.next;
        } while( currentNode != null );
    
    }
}
编码在任何给定位置插入节点的方法的一种方法是什么?

public void insertAt(int index,Song-Song){
public void insertAt(int index, Song song) {
    // First, check the inputs
    if (index > size)
        throw new IndexOutOfBoundsException();

    if (song == null)
        throw new NullPointerException();
    
    // Skip (index - 1) songs from the beginning (this), keeping track of previous entry
    Song cur = this, prev = null;
    for (int i = 0; i < index; i++) {
        prev = cur;
        cur = cur.next;
    }

    // Insert in between previous and current entry
    if (prev != null)
        prev.next = song;

    song.next = cur;
    ++size;
}
//首先,检查输入 如果(索引>大小) 抛出新的IndexOutOfBoundsException(); 如果(歌曲==null) 抛出新的NullPointerException(); //从开头跳过(索引-1)首歌曲(此),跟踪上一个条目 Song cur=this,prev=null; 对于(int i=0;i

可以在

上找到一个好的可视化效果,但这不是您所要求的,但这是一个常见错误-一首
歌曲
不应该有一个
下一首
。当您有一个链表时,每个元素都有一个
next
,并且应该有一个
——在您的情况下,该值是一个歌曲对象;因此,列表
节点
对象应该有一个值和一个下一个值(否则,任何类型的对象都必须有一个“下一个”),谢谢你的VisuAlgo链接,它非常棒,帮助我可视化事物。你能解释一下你的解决方案吗?它对我不起作用,我不断出错。@Dasax121我忘了提到在列表中存储歌曲的数量很方便,所以您需要向类中添加一个新字段,
private int size=1
,并在每次添加新元素时递增它,就像在这个方法和
append
@Dasax121中一样,当index=0时,此代码将不起作用,因为我们将
视为列表的开头。有两种解决方案:使
insertAt
返回列表的开头,当
index==0
时,返回
song
,否则返回
this
。这显然不是很方便。更好的方法是为列表使用包装类,即
相册
,并保留一个sentinel元素(一个空的
歌曲
)作为起始元素,因此列表的实际元素将位于该元素之后,并且在起始处插入一个元素与任何其他位置都没有区别。@Dasax121,必须相应地修改遍历,如转到循环第一行的
下一个
,以跳过哨兵。
public void insertAt(int index, Song song) {
    // First, check the inputs
    if (index > size)
        throw new IndexOutOfBoundsException();

    if (song == null)
        throw new NullPointerException();
    
    // Skip (index - 1) songs from the beginning (this), keeping track of previous entry
    Song cur = this, prev = null;
    for (int i = 0; i < index; i++) {
        prev = cur;
        cur = cur.next;
    }

    // Insert in between previous and current entry
    if (prev != null)
        prev.next = song;

    song.next = cur;
    ++size;
}