2016-11-06 3 views
0

私はこのコードを一週間のように感じていて、何が起こっているのか分からない。私は現在、LinkedListに500要素を追加する必要があります。私が要素0を追加している最初の実行では、正常に動作します。それはそれが最初の要素であることを見て、新しい頭を作り、動きます。問題は、コードが要素1を追加するために周りに戻ってきたときに、ヘッドが突然nullにリセットされたため、別のヘッドを作成して前のヘッドを追い出すことです。 3回目の実行では、コードは頭が存在することを認識し、要素2を追加しようとします。nは、LinkedListに2つの要素があると主張します。したがって、その2番目の要素を探すときにNullPointerExceptionがスローされます。最初の頭に何が起こっているのですか?それはadd()メソッドを通してすべての方法を行いますが、それが戻ってくるとそこにはありません。しかし、それが再び来るときにそこにありますか?リンクされたリストの頭が突然消えてしまう/ヌルにリセットされる

は、ここですべてが間違っている特定の方法です:

public void add(int i, value_type value) { 
    n++; 
    System.out.println(head==null); 
    if (i < 0 || i >= size()) 
     throw new IndexOutOfBoundsException(); 

    System.out.println(i); 
    ListNode<value_type> tmp; 
    if (head == null) { 
     System.out.println("0"); 
     head = new ListNode<value_type>(value, head); 
    } else { 
     System.out.println("1"); 
     tmp = head; 
     for (int k=0; k < i-1; k++) { 
      System.out.println("For Loop Reached"); 
      tmp = tmp.next; 
     } 
     if (i == 1) { 
      ListNode<value_type> u = new ListNode<value_type>(value); 
      tmp.next = u; 
     } 

     tmp.next = new ListNode<value_type>(value); 

    } 
    System.out.println(head==null); 
    System.out.println(""); 
} 

そして、ここでは全体のクラスです:

/** 
* 
*/ 
package data_structures; 

import com.sun.corba.se.impl.orbutil.graph.Node; 

/** 
* @author 
* 
*/ 

/** 
* The ListNode<value_type> is a helper class for your 
* LinkedList<value_type> class. As its not intended for use 
* outside the LinkeList class, we are keeping it simple -- the 
* two properties will be access directly, instead of going through 
* inspectors and mutators. 
* 
* DO NOT MODIFY THIST CLASS. 
* 
* @param <value_type> The type of object to be stored in the list. 
*/ 
class ListNode<value_type> { 
    public value_type value; 
    public ListNode<value_type> next; 

    public ListNode(value_type v) { 
     value = v; 
     next = null; 
    } 

    public ListNode(value_type v, ListNode<value_type> n) { 
     value = v; 
     next = n; 
    } 

} 


/* 
* We will implement this as a single linked list. 
*/ 
public class LinkedList<value_type> extends Sequence<value_type> { 

    /** 
    * head will be the first node of the list -- or null if the list is empty 
    */ 
    private ListNode<value_type> head; 


    /** 
    * List constructor: must call the superclass constructor. 
    */ 
    public LinkedList() { 
     super(); 
     head = null; 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#get(int) 
    */ 
    @Override 
    public value_type get(int i) { 
     if (i < 0 || i >= size()) 
      throw new IndexOutOfBoundsException(); 

     ListNode<value_type> tmp = head; 
     for (int k=0; k < i; k++) { 
      tmp = tmp.next; 
     } 


     return tmp.value; 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#set(int, java.lang.String) 
    */ 
    @Override 
    public value_type set(int i, value_type value) { 
     if (i < 0 || i >= size()) 
      throw new IndexOutOfBoundsException(); 

     if (head == null) { 
      throw new IndexOutOfBoundsException(); 
     } 

     ListNode<value_type> tmp = head; 
     for (int k=0; k < i; k++) { 
      tmp = tmp.next; 
     } 

     if (tmp == null) { 
      throw new IndexOutOfBoundsException(); 
     } 

     return tmp.value; 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#add(int, java.lang.String) 
    */ 
    @Override 
    public void add(int i, value_type value) { 
     n++; 
     System.out.println(head==null); 
     if (i < 0 || i >= size()) 
      throw new IndexOutOfBoundsException(); 

     System.out.println(i); 
     ListNode<value_type> tmp; 
     if (head == null) { 
      System.out.println("0"); 
      head = new ListNode<value_type>(value, head); 
     } else { 
      System.out.println("1"); 
      tmp = head; 
      for (int k=0; k < i-1; k++) { 
       System.out.println("For Loop Reached"); 
       tmp = tmp.next; 
      } 
      if (i == 1) { 
       ListNode<value_type> u = new ListNode<value_type>(value); 
       tmp.next = u; 
      } 

      tmp.next = new ListNode<value_type>(value); 

     } 
     System.out.println(head==null); 
     System.out.println(""); 

    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#remove(int) 
    */ 
    @Override 
    public value_type remove(int i) { 
     if (i < 0 || i >= size()) 
      throw new IndexOutOfBoundsException(); 

     ListNode<value_type> tmp = head; 
     for (int k=0; k < i; k++) { 
      tmp = tmp.next; 
     } 

     ListNode<value_type> a = tmp; 
     ListNode<value_type> b = tmp.next.next; 
     a.next = b; 

     return tmp.value; 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#clear() 
    */ 
    @Override 
    public void clear() { 
     head = null; 
    } 



} 
+0

、あなたの実際のコードで、このリンクリストの使用を共有してくださいことはできますか? – mtyurt

+0

あなたは私のプロジェクトの残りのコードを意味しますか? –

+0

'remove'関数は頭を除去するのに安全ではなく、バグです。それは問題かもしれません。私はリンクリストの実装例を見ることをお勧めします。 – mtyurt

答えて

0

私はGeneが参照していると信じているように、i=0i=1という特殊なケースを追加して考え出しました。リストの末尾に追加するためのテール変数も追加しました。

public void add(int i, value_type value) { 
    if (i < 0 || i > size()) 
     throw new IndexOutOfBoundsException(); 

    //if the size of the list is 0, create a new head 
    if (n==0) { 
     head = new ListNode<value_type>(value, head); 
     tail = head; 
    } else if (i==0) { //if the size isn't 0, but i is 0, add a new head 
     ListNode<value_type> u = new ListNode<value_type>(value, head); 
     head = u; 
    } else if (i==n) { //if adding onto the end, make a new tail 
     ListNode<value_type> u = new ListNode<value_type>(value); 
     tail.next = u; 
     tail = u;   
    } else { //else, traverse through the list to the appropriate spot 
     ListNode<value_type> tmp; 
     tmp = head; 
     for(int k=0; k < i-1; k++) { 
      tmp = tmp.next; 
     } 
     ListNode<value_type> u = new ListNode<value_type>(value, tmp.next); 
     tmp.next = u; 
    } 

    n++; //increase the size of the list by 1 

} 

固定クラスの残りの部分は以下の通りです:

/** 
* 
*/ 
package data_structures; 

import com.sun.corba.se.impl.orbutil.graph.Node; 

/** 
* The ListNode<value_type> is a helper class for your 
* LinkedList<value_type> class. As its not intended for use 
* outside the LinkeList class, we are keeping it simple -- the 
* two properties will be access directly, instead of going through 
* inspectors and mutators. 
* 
* DO NOT MODIFY THIST CLASS. 
* 
* @param <value_type> The type of object to be stored in the list. 
*/ 
class ListNode<value_type> { 
    public value_type value; 
    public ListNode<value_type> next; 

    public ListNode(value_type v) { 
     value = v; 
     next = null; 
    } 

    public ListNode(value_type v, ListNode<value_type> n) { 
     value = v; 
     next = n; 
    } 

} 


/* 
* We will implement this as a single linked list. 
*/ 
public class LinkedList<value_type> extends Sequence<value_type> { 

    /** 
    * head will be the first node of the list -- or null if the list is empty 
    */ 
    private ListNode<value_type> head, tail;      

    /** 
    * List constructor: must call the superclass constructor. 
    */ 
    public LinkedList() { 
     super(); 
     head = null; 
     tail = null; 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#get(int) 
    */ 
    @Override 
    public value_type get(int i) { 
     if (i < 0 || i >= size()) 
      throw new IndexOutOfBoundsException(); 


     ListNode<value_type> tmp = head; 
     if (i==0) { 
      return head.value; 
     } else { 
      for (int k=0; k < i; k++) { 
       tmp = tmp.next; 
      } 
     } 


     return tmp.value; 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#set(int, java.lang.String) 
    */ 
    @Override 
    public value_type set(int i, value_type value) { 
     System.out.println(n); 
     if (i < 0 || i >= size()) 
      throw new IndexOutOfBoundsException(); 

     if (i==0) { 
      value_type s = head.value; 
      head.value = value; 
      return s; 
     } else { 
      ListNode<value_type> tmp = head; 
      for (int k=0; k < i; k++) { 
       tmp = tmp.next; 
      } 
      value_type s = tmp.value; 
      tmp.value = value; 
      return s; 
     } 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#add(int, java.lang.String) 
    */ 
    @Override 
    public void add(int i, value_type value) { 
     if (i < 0 || i > size()) 
      throw new IndexOutOfBoundsException(); 

     if (n==0) { 
      head = new ListNode<value_type>(value, head); 
      tail = head; 
     } else if (i==0) { 
      ListNode<value_type> u = new ListNode<value_type>(value, head); 
      head = u; 
     } else if (i==n) { 
      ListNode<value_type> u = new ListNode<value_type>(value); 
      tail.next = u; 
      tail = u;   
     } else { 
      ListNode<value_type> tmp; 
      tmp = head; 
      for(int k=0; k < i-1; k++) { 
       tmp = tmp.next; 
      } 
      ListNode<value_type> u = new ListNode<value_type>(value, tmp.next); 
      tmp.next = u; 
     } 

     n++; 

    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#remove(int) 
    */ 
    @Override 
    public value_type remove(int i) { 
     if (i < 0 || i >= size()) 
      throw new IndexOutOfBoundsException(); 

     ListNode<value_type> tmp = head; 
     if (i==0) { 
      if (n==1) { 
       head.next = null; 
       n--; 
       return head.value; 
      } else { 
       value_type save = head.value; 
       head = head.next; 
       n--; 
       return save; 
      } 
     } 
     for (int k=0; k < i-1; k++) { 
      tmp = tmp.next; 
     } 

     ListNode<value_type> a = tmp; 
     value_type save = tmp.next.value; 
     ListNode<value_type> b = tmp.next.next; 
     a.next = b; 

     n--; 

     return save; 
    } 

    /* (non-Javadoc) 
    * @see data_structures.Sequence#clear() 
    */ 
    @Override 
    public void clear() { 
     head = null; 
     n = 0; 
     tail=null; 
    } 



} 
0

コードはかなり壊れています。あなたはそれを自分で修正することによって学びます。

headnullの場合、正しく挿入するための特別なケースはありません。あなたは論理0の位置に挿入したいときには、最後のステップでおおよそ

if desired insert position is 0 // we're inserting at head 
    head = new node(val, head); // new head points to old rest of list (maybe null) 
else 
    tmp = head; 
    advance tmp to point to the element before the desired position. 
    tmp.next = new node(val, tmp.next); // insert at desired position 

である、あなたは、次の「旧への新しいノードに目的の位置ポイントを前のノードと新しいノードポイントを作っているのです"要素は、まさに正しいものです。これは、の場合は、希望する位置の前の要素です。これは、希望の位置が0より大きい場合に当てはまります。

この説明では、リスト外の希望の位置は無視しています。それらのためにロジックthrowを追加する必要があります。

最後に、これはうまくいくことを覚えておいてくださいが、実際のシステムでは、このように500個の要素のリストを作成することはありません。 500番目の要素を挿入するときまでに、希望の位置に進むには498回のループ反復が必要です。はるかに効率的な方法があります。

+0

リストの最後に要素を追加する場合、 'tmp.next'がまだ存在しないので、単に' tmp.next'を呼び出して新しいノードに設定することはできません。だから、新しいノードを 'next'として設定したノードを作成し、その2つをリストの最後に追加する必要があります。それは面倒だ。 –

関連する問題