0

結點類別我的代碼有什麼問題? (鏈表的Java /洗牌)

public class NodeDouble{ 
    private int card; 
    NodeDouble next; 
    NodeDouble prev; 

    public NodeDouble(int card){ 
     this.card = card; 
    } 

    public int getCard(){ 
     return this.card; 
    } 

    public NodeDouble getNext(){ 
     return this.next; 
    } 

    public NodeDouble getPrev(){ 
     return this.prev; 
    } 

    public void displayNode(){ 
     System.out.println("Card: "+card); 
    } 
} 

LinkedList類

import java.util.Random; 

public class CardListDouble{ 

private NodeDouble head; 
private NodeDouble tail; 
private int size; 

//constructors 
public CardListDouble(){ 
    head = null; 
    tail = null; 
    size = 0; 
} 
public CardListDouble(int numberOfCards){ 
    for(int i = numberOfCards; i>=1; i--){ 
     this.insertFirst(i); 
    } 
    size = numberOfCards; 
} 
//methods 
public void insert(int card, int index){ 
    if(index < 1 || index > size+1){throw new IllegalArgumentException("index is smaller than 1!, or larger than size!");} 
    else if(index == 1){//add at beginning 
     insertFirst(card); 
    } 
    else if(index == size+1){//add to the end 
     NodeDouble temp = new NodeDouble(card); 

     tail.next = temp; 
     temp.prev = tail; 
     tail = temp; 
    }else{//add to the 'middle' somewhere 
     NodeDouble temp = new NodeDouble(card); 
     NodeDouble indexmin1 = getNode(index-1); 
     NodeDouble indexcurrent = getNode(index); 

     indexmin1.next = temp; 
     temp.next = indexcurrent; 
     indexcurrent.prev = temp; 
     temp.prev = indexmin1; 
    }size++; 
} 

public void insertFirst(int card){ 
    NodeDouble temp = new NodeDouble(card); 

    if(isEmpty()){ 
     head = temp; 
     tail = temp; 
    }else{ 
     temp.next = head; 
     head.prev = temp; 
     head = temp; 
    }size++; 
} 

public int removeCard(int card){ 
    if(card > size){throw new IllegalArgumentException("card not here!");} 
    if(head == null){System.out.println("cannot delete from empty list");} 
    else{ 
     NodeDouble current = head; 
     NodeDouble oneBehind = null; 
     boolean found = false; 
     int fua = 0; 
     //traverse list to find which node/card to delete 
     while(found == false && fua < size){ 
      fua++; 
      if(current.getCard() == card){ 
       found = true; 
       break; 
      }else{ 
       current = current.next; 
      } 

     } 
     //did not find node 
     if(current == null){System.out.println("Card not in list!");} 
     //did find node 
     else{ 
      int tempCard = current.getCard(); 
      if(head == current){//case1; card is at head 
        head = head.next; 
        head.prev = null; 
       } 
       else if(current == tail){//case2; card is tail 
        tail = tail.prev; 
        tail.next = null; 
       } 
       else{//card is in the 'middle' somewhere 
       current.prev.next = current.next; 
       current.next.prev = current.prev; 
       current.next = null; 
       current.prev = null; 
       }size--;return tempCard; 
      } 
     }return 0;//did not find card so return 0; 
    } 




public NodeDouble getNode(int index){ 
    if(index <=0){throw new IllegalArgumentException("index < 1 yo! (getnodemethod)");} 
    else if(index > size){throw new IllegalArgumentException("index is bigger than size!");} 
    else if(index < (size/2)){//traverse from right 
     NodeDouble current = head; 
     for (int i = 1; i < index; i++) { 
      current = current.next; 
     }return current; 
    }else if(index >= (size/2)){//traverse from left 
     NodeDouble current = tail; 
     for (int i = size; i > index; i--) { 
      current = current.prev; 
     }return current; 
    }else{ 
     System.out.println("list is empty or index is smaller than 0!"); 
     return null; 
    } 
} 

public void displayList(){ 
    if(isEmpty()){ 
     System.out.println("Empty List!"); 
    }else{ 
     NodeDouble current = head; 

     while(current != null){ 
      current.displayNode(); 
      current = current.next; 
     } 
    }System.out.println("size of deck:" + size); 
} 
public boolean isEmpty(){ 
    return size == 0; 
} 

public void shuffle(){ 
    Random rng = new Random(); 
    for(int i = 1; i<size; i++){ 
     int temp = rng.nextInt(size) + 1; 
     System.out.println("i:" + i + " temp: " + temp); 
     removeCard(i); 
     insert(i,temp); 
    } 
    System.out.println("shuffling done!"); 
} 
} 

測試/ main方法

public class Test{ 

    public static void main(String[] args){ 
     CardListDouble list = new CardListDouble(52); 

     long startTime = System.currentTimeMillis(); 
     list.shuffle(); 
     list.displayList(); 
     long estimatedTime = System.currentTimeMillis() - startTime; 
     System.out.println("Time taken: " + estimatedTime); 
    } 

大家嗨。我正在製作一個雙鏈表來包含一些卡片。 一切似乎工作正常(當我測試每個方法本身似乎工作)。 但是當我運行shuffle方法時,偶爾我會得到一個NullPointerException,我似乎無法找出問題所在。

在shuffle方法中,我只有一個for循環,它可以刪除for循環所在的卡。然後它將它插入列表中的隨機位置。

我是初學者,所以我希望你能理解我的代碼。我添加了一些評論。

回答

0

在您的insert方法中,您的案例之一調用insertFirst並繼續。發生這種情況時,insertFirst遞增列表大小,然後insert再次遞增列表大小。現在列表的大小太大,當它結束時,你會在remove中得到NullPointerException

解決此特定問題的一種方法是在insert致電insertFirst(card)後添加return

+0

謝謝老兄,解決了這個問題。你是我的英雄:D。我還可以問你用什麼方法來發現問題嗎? –

+0

我在循環中運行你的代碼來複制問題。 shuffle中的代碼會打印多少次它會循環超過大小,並且它已經超過了53次,所以很明顯,大小增加了太多次。我研究了它可能改變的地方,並試圖找到一條可能改變多次的路徑。 –