[Java] Dubbellänkad lista, sorteringsproblem

Permalänk
Medlem

[Java] Dubbellänkad lista, sorteringsproblem

Hej svej! Har i läxa att skriva två klasser för en dubbellänkad lista, såhär ser min kod ut hittills:

/** * Klassen "Node" skapar och hanterar noder för användning i länkade listor. * * @version 0.1 */ public class Node{ /** * Konstruerar en Node utan referenser och värde. */ public Node(){} /** * Konstruerar en Node utan referenser med valt värde * * @param _i Nodens värde */ public Node(int _i){ i = _i; } /** * Konstruerar en Node med referens bakåt och framåt samt valt värde * * @param _i Nodens värde * @param _next Nodens referens framåt * @param _prev Nodens referens bakåt */ public Node(int _i, Node _next, Node _prev){ i = _i; next = _next; prev = _prev; } int i; Node next; Node prev; /** * Tilldelar noden specifierat värde * * @param _i Specifierat värde */ public void setValue(int _i){ i = _i; } /** * Tilldelar noden en referens framåt * * @param _next Referens framåt */ public void setNext(Node _next){ next = _next; } /** * Tilldelar noden en referent bakåt * * @param _prev Referens bakåt */ public void setPrev(Node _prev){ prev = _prev; } /** * Returnerar nodens värde * * @return nodens värde */ public int getValue(){ return i; } /** * Returnerar nodens referens framåt * * @return referens framåt */ public Node getNext(){ return next; } /** * Returnerar nodens referens bakåt * * @return referens bakåt */ public Node getPrev(){ return prev; } public String toString(){ String s = "Värde: "+i; return s; } } /*********************************************/ /*********************************************/ /** * Klassen "DoubleLinked" skapar och hanterar dubbellänkade listor ihop med klassen "Node". * * @version 0.1 */ public class DoubleLinked{ Node n; Node first; Node last; public DoubleLinked(){} public void addFirst(Node _n){ if(first==null){ first = _n; last = _n; _n.setPrev(null); _n.setNext(null); } else{ _n.setPrev(null); _n.setNext(first); first.setPrev(_n); first = _n; } } public void addLast(Node _n){ if(last==null){ addFirst(_n); } else{ _n.setNext(null); _n.setPrev(last); last.setNext(_n); last = _n; } } //_nP, _nN can be null public void addBetween(Node _n, Node _nP, Node _nN){ _n.setNext(_nN); _n.setPrev(_nP); if(_nN == null) last = _n; else _nN.setPrev(_n); if(_nP == null) first = _n; else _nP.setNext(_n); } public void remove(Node _n){ if(_n.getNext() == null){ _n.getPrev().setNext(null); last = _n.getPrev(); } else if(_n.getPrev() == null){ _n.getNext().setPrev(null); first = _n.getNext(); } else{ _n.getNext().setPrev(_n.getPrev()); _n.getPrev().setNext(_n.getNext()); _n = null; } } public Node getWithValue(int _i){ n = first; while(n.getNext() != null){ if(n.getValue() == _i){ return n; } else{ n=n.getNext(); } } return null; } public Node getLast(){ return last; } public Node getFirst(){ return first; } public void sortDes(){ boolean sorted = false; while(!sorted){ sorted = true; for(Node cur=first;cur.getNext()!=null;cur=cur.getNext()){ if(cur.getValue() < cur.getNext().getValue()){ addBetween(cur, cur.getNext(), cur.getNext().getNext()); sorted = false; } } } } public String toString(){ StringBuilder result = new StringBuilder(); n = first; while(n != null){ result.append(n+"\n"); n = n.getNext(); } return result.toString(); } }

Mitt problem just nu är att när jag kör sortDes() i mitt testprogram så får jag nullpointer exception på raden med:

for(Node cur=first;cur.getNext()!=null;cur=cur.getNext()){

Jag kan verkligen inte lista ut varför jag får det så skulle uppskatta det väldigt mycket om någon kunde kolla igenom min kod och se vad som kan vara fel

Permalänk

Kör du addfirst innan?

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem

Japp, när jag kör testprogrammet kan jag välja om jag ska använda addFirst() eller addLast() och har hittills bara testat att lägga till värden med addFirst().
Här är testprogrammet om det hjälper:

import java.util.*; public class Linking{ public static void main(String[] args){ boolean prog = true; Scanner scan = new Scanner(System.in); DoubleLinked list = new DoubleLinked(); while(prog){ System.out.println("Tryck\n1.Lägg heltal först i lista\n2.Lägg heltal sist i lista\n3.Skriv ut lista\n4.Sortera lista\n5.Ta bort tal ifrån lista\n0.Avsluta programmet\n"); String s = scan.next(); if(s.equals(""+1)){ System.out.println("Skriv heltal separerade med radbrytning eller mellanslag\nSkriv END för att avsluta"); boolean addfirst = true; while(addfirst){ s = scan.next(); if(s.equals("END")){ addfirst = false; } else{ list.addFirst(new Node(Integer.parseInt(s))); } } } else if(s.equals(""+2)){ System.out.println("Skriv heltal separerade med radbrytning eller mellanslag\nSkriv END för att avsluta"); boolean addlast = true; while(addlast){ s = scan.next(); if(s.equals("END")){ addlast = false; } else{ list.addLast(new Node(Integer.parseInt(s))); } } } else if(s.equals(""+3)){ System.out.println(list); } else if(s.equals(""+4)){ list.sortDes(); System.out.println(list); } else if(s.equals(""+5)){ System.out.println(list+"\nVilket värde ska tas bort?"); int i = scan.nextInt(); list.remove(list.getWithValue(i)); System.out.println(list); } else if(s.equals(""+0)){ break; } else{ System.out.println("Var god försök igen."); } } } }

Permalänk

Får du ut vilken variabel som är null?

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av KurreKula
Får du ut vilken variabel som är null?

Nope, såhär blir det:

Permalänk
Medlem

Det smartaste är väll att debugga, sätta break points på alla funktioner du använder & kontrollerar datan, man brukar hitta fel på det sättet, ofta kan dom vara helt åt pipsvängen ibland bara att man inte tittat riktigt

Permalänk

Ser ett potentiellt nullpointerexception på en annan rad:

addBetween(cur, cur.getNext(), cur.getNext().getNext());

Hur vet du att "cur.GetNext().getNext()" inte är null?

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av KurreKula
Ser ett potentiellt nullpointerexception på en annan rad:

addBetween(cur, cur.getNext(), cur.getNext().getNext());

Hur vet du att "cur.GetNext().getNext()" inte är null?

Har funderat på det med så jag la till en if-sats som kollar det och får samma fel :/

Permalänk
Citat:

Ursprungligen inskrivet av Axfred
Har funderat på det med så jag la till en if-sats som kollar det och får samma fel :/

Skrev om ditt program till c# och debuggar i visual studio. Som du säger får man inte fel på alla värden men när jag fick fel så är det när man anropar "cur.getNext() != null", då är cur = null, vilket ger felet
ändrar du till följande:

for (Node cur = first; cur != null && cur.getNext() != null; cur = cur.getNext())

får du inget exception.

Edit: det som händer är att första loopen så blir cur = first. Men andra loopen blir först cur = getNext(), och sen kollar den att cur.getNext() inte är null. Men cur kan ha blivit null innan kollen.. Hoppas du förstår vad jag menar... Första loopen körs såhär:
for(1;2;0)
sen körs det:
for(0;2;1)
där siffran är vilket ordning den körs i och 0 innebär att den inte körs alls

Edit1: skrev om koden till att var lite snyggare, ändrade dina get och set till att vara properties:

/** * Klassen "Node" skapar och hanterar noder för användning i länkade listor. * * @version 0.1 * @author Alfred Kronlid */ public class Node { public int Value{get;set;} public Node Next { get; set; } public Node Prev { get; set; } /** * Konstruerar en Node utan referenser och värde. */ public Node() { } /** * Konstruerar en Node utan referenser med valt värde * * @param _i Nodens värde */ public Node(int _i) { Value = _i; } /** * Konstruerar en Node med referens bakåt och framåt samt valt värde * * @param _i Nodens värde * @param _next Nodens referens framåt * @param _prev Nodens referens bakåt */ public Node(int _i, Node _next, Node _prev) { Value = _i; Next = _next; Prev = _prev; } public override string ToString() { return string.Format("Värde{0}: ", Value); } }

/*********************************************/ /*********************************************/ /** * Klassen "DoubleLinked" skapar och hanterar dubbellänkade listor ihop med klassen "Node". * * @version 0.1 * @author Alfred Kronlid */ public class DoubleLinked { Node n; Node first; Node last; public DoubleLinked() { } public void addFirst(Node _n) { if (first == null) { first = _n; last = _n; _n.Prev = null; _n.Next = null; } else { _n.Prev = null; _n.Next = first; first.Prev = _n; first = _n; } } public void addLast(Node _n) { if (last == null) { addFirst(_n); } else { _n.Next = null; _n.Prev = last; last.Next = _n; last = _n; } } //_nP, _nN can be null public void addBetween(Node _n, Node _nP, Node _nN) { _n.Next = _nN; _n.Prev = _nP; if (_nN == null) last = _n; else _nN.Prev = _n; if (_nP == null) first = _n; else _nP.Next = _n; } public void remove(Node _n) { if (_n.Next == null) { _n.Prev.Next = null; last = _n.Prev; } else if (_n.Prev == null) { _n.Next.Prev = null; first = _n.Next; } else { _n.Next.Prev = _n.Prev; _n.Prev.Next = _n.Next; _n = null; } } public Node getWithValue(int _i) { n = first; while (n.Next != null) { if (n.Value == _i) { return n; } else { n = n.Next; } } return null; } public Node getLast() { return last; } public Node getFirst() { return first; } public void sortDes() { bool sorted = false; while (!sorted) { sorted = true; for (Node cur = first; cur != null && cur.Next != null; cur = cur.Next) { if (cur.Value < cur.Next.Value) { addBetween(cur, cur.Next, cur.Next.Next); sorted = false; } } } } public override String ToString() { StringBuilder result = new StringBuilder(); n = first; while (n != null) { result.Append(n.ToString() + "\n"); n = n.Next; } return result.ToString(); } }

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem

Tack så hemskt mycket för hjälpen

Permalänk
Citat:

Ursprungligen inskrivet av Axfred
Tack så hemskt mycket för hjälpen

Det var så lite så

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase