【问题标题】:Java Implementation of a Linked List链表的 Java 实现
【发布时间】:2021-06-28 10:01:25
【问题描述】:

我正在参考我学校的教科书,尝试在 java 中实现一个链表。

要查看列表,我对每个节点使用 getInfo() 方法,该方法应返回列表中每个人的姓名和姓氏(我正在实现人员列表)。

我不明白为什么我的教科书在类 Node 的方法 getInfo() 中返回一个 new Invitato(info) 而不是存储在类 Nodo 中的那个。

如果我尝试返回存储在 Nodo 类中的那个,我会得到一个空指针异常。

public class Main{
    public static void main(String args[]){
        
        Invitato i1 = new Invitato("Michele","Bianchi");
        Invitato i2 = new Invitato("Paolo","Rossi");
        Invitato i3 = new Invitato("Mario","Verdi");
        Invitato i4 = new Invitato("Giacomo","Neri");

        Lista l = new Lista();

        l.inserisciInCoda(i1);
        l.inserisciInTesta(i2);
        l.inserisciInTesta(i3);
        l.inserisciInPosizione(i4,2);

        l.visitaLista();
    }
}


public class Lista{
    private Nodo head;
    private int elementi;

    public Lista(){
        elementi=0;
        head = null;
    }

    private Nodo creaNodo(Invitato invitato, Nodo link){
        Nodo nuovoNodo = new Nodo(invitato);
        nuovoNodo.setLink(link);
        return nuovoNodo;
    }

    public int getElementi(){
        return elementi;
    }

    private Nodo getLinkPosizione(int n){
        Nodo p = head; 
        int i = 1;

        if(n>elementi || n<1)
            return null;
        else{
            while(p.getLink() != null && i<n){
                p = p.getLink();
                i++;
            }
        }
        return p;
    }

    public void visitaLista(){
        Nodo p = head;
        if(p==null){
            System.out.println("Lista vuota");
        }
        else{
            while(p!=null){
                System.out.println(p.getInfo().toString());
                p = p.getLink();
            }
        }
    }

public void inserisciInTesta(Invitato invitato){
        Nodo p = creaNodo(invitato, head);      //creo un nuovo nodo e lo liko alla testa
        head = p;                             //il nuovo nodo diventa la head
        elementi++;
    }

    public void inserisciInCoda(Invitato invitato){
        if(head==null){                             //se la lista è vuota
            inserisciInTesta(invitato);          //posso inserire il nuovo nodo in testa
        }

        else{
            Nodo p = getLinkPosizione(elementi);            //prendo l'ultimo nodo
            Nodo nuovoNodo = creaNodo(invitato, null);
            p.setLink(nuovoNodo);
            elementi++;
        }
    }

    public void inserisciInPosizione(Invitato invitato, int posizione){
        if(posizione <=1){
            inserisciInTesta(invitato);
        }
        else{
            if(posizione > elementi){
                inserisciInCoda(invitato);
            }
            else{
                Nodo p = getLinkPosizione(posizione-1);
                Nodo nuovoNodo = creaNodo(invitato,p.getLink());
                p.setLink(nuovoNodo);
                elementi++;
            }
        }
    }

    public void eliminaInTesta(){
        if(head == null)    //la lista è vuota?
            return;
        head = head.getLink(); //la nuova head è il nodo a cui linka, quindi ora head riferisce al secondo nodo
        elementi--;
    }

    public void eliminaInCoda(){
        if(head == null){               //lista vuota
            return;
        }
        Nodo p = getLinkPosizione(elementi-1);    //prendo il penultimo nodo
        p.setLink(null);                // e metto il suo link a null
        elementi--;
    }

    public void eliminaInPosizione(int n){
        if(n<=1){
            this.eliminaInTesta();
        }
        else{
            if(n>=elementi){
                this.eliminaInCoda();
            }
            else{
                Nodo pp = getLinkPosizione(n-1);         //nodo prima di quello da cancellare
                Nodo ps = getLinkPosizione(n);          //nodo da cancellare
                
               pp.setLink(ps.getLink());                //assegno al link precedente a quello da cancellare il link di quello che sto cancellando
               elementi--;
            }
        }
    }
}

public class Invitato{
    private String nome;
    private String cognome; 

    public Invitato(String nome, String cognome){
        this.nome = nome;
        this.cognome = cognome;
    }

    public Invitato(Invitato invitato){
        this.nome = invitato.getNome();
        this.cognome = invitato.getCognome();
    }

    public String getNome(){
        return nome;
    }

    public String getCognome(){
        return cognome; 
    }

    public String toString(){
        return nome + " " + cognome+";";
    }
}

public class Nodo{
    private Invitato info; 
    private Nodo link;

    public Nodo(Invitato invitato){
        this.invitato = new Invitato(invitato);
        link = null;
    }

    public Invitato getInfo(){
        return new Invitato(info);
    }

    public void setLink(Nodo link){
        this.link = link;
    }

    public Nodo getLink(){
        return link;
    }    
}

【问题讨论】:

  • getInfo() 正在返回 Nodo 中的邀请副本。如果没有看到 NPE 的完整堆栈跟踪,就无法判断出了什么问题。
  • 未来的小提示:用英语而不是意大利语编写代码。当然,代码无论如何都可以工作,但是任何人都很难阅读和理解你的工作(即使对我来说,我是意大利人!)
  • 这还能编译吗?在您的 Nodo 类构造函数中,您有 this.invitato = ... 但该类没有任何名为 invitato 的字段。

标签: java list object linked-list model


【解决方案1】:

Nodo的构造函数错误:
this.invitato = new Invitato(invitato);
应该是:
this.info= new Invitato(invitato);

而且您不需要在 Nodo 的构造函数和 getInfo 方法中构建 Invitato 的新实例:

    public Nodo(Invitato invitato){
        this.info = invitato;
        link = null;
    }
    public Invitato getInfo(){
        return info;
    }

一旦构造函数修复,我就有了一个列表,没有任何异常:

Mario Verdi;
Giacomo Neri;
Paolo Rossi;
Michele Bianchi;

【讨论】:

  • 非常感谢,除了信息和邀请不匹配我使用的教科书方法对我没有意义。
猜你喜欢
  • 2016-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 2012-10-15
  • 1970-01-01
相关资源
最近更新 更多