• 締切済み

教えて。

双方向リストを書いているのですが、指定したノードの次に新たなノード追加以降からどうしてもうまくできません。 できればソースで教えてもらえれば助かります。 class MyListw{ int data; //データ MyListw next = null; MyListw prev = null; MyListw firstNode = null; MyListw lastNode = null; MyListw(int data){ this.data = data; } void insertTail(MyListw newNode){ if(lastNode == null) insertHead(newNode); else insertAfter(lastNode, newNode); } void insertHead(MyListw newNode){ if(firstNode == null){ firstNode = newNode; lastNode = newNode; newNode.prev = null; newNode.next = null; }else{ insertBefore(firstNode, newNode); } } void insertAfter(MyListw node, MyListw newNode){ //指定したノードの次に新たなノード追加 newNode.prev = node; newNode.next = node.next; if(node.next == null) lastNode = newNode; else node.next.prev = newNode; node.next = newNode; } void insertBefore(MyListw node, MyListw newNode){ //指定したノードの前に新たなノード newNode.prev = node.prev; newNode.next = node; if(node.prev == null) firstNode = newNode; else node.prev.next = newNode; node.prev = newNode; } void delete(MyListw node){ //リストからデータを1つ削除 if(node.prev == null) firstNode = node.next; else node.prev.next = node.next; if(node.next == null) lastNode = node.prev; else node.next.prev = node.prev; } void deleteHead(){ //先頭のノードを削除 delete(firstNode.next); } void deleteTail(){ //最後のノードを削除 delete(lastNode.prev); } void show(){ MyListw node = firstNode; while(node != null){ System.out.print(node.data); node = node.next; } System.out.println(""); } void showTail(){ MyListw node = lastNode; while(node != null){ System.out.print(node.data); node = node.prev; } } } class MyListwApp{ public static void main(String[] args){ MyListw list = new MyListw(0); //初期ダミー System.out.println("最後に追加"); list.insertTail(new MyListw(1)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("\n"); list.insertTail(new MyListw(5)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("先頭に追加"); list.insertHead(new MyListw(8)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("\n"); list.insertHead(new MyListw(9)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("指定したノードの次に新たなノード追加"); list.insertAfter(new MyListw(1), new MyListw(2)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("\n"); list.insertAfter(new MyListw(2), new MyListw(3)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("指定したノードの前に新たなノード"); list.insertBefore(new MyListw(1), new MyListw(0)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("リストからデータを削除"); list.delete(new MyListw(1)); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("先頭のノードを削除"); list.deleteHead(); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("\n"); list.deleteHead(); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("最後のノードを削除"); list.deleteTail(); list.show(); System.out.println("逆順に表示"); list.showTail(); System.out.println("\n"); list.deleteTail(); list.show(); System.out.println("逆順に表示"); list.showTail(); } }

みんなの回答

  • tekebon
  • ベストアンサー率62% (36/58)
回答No.2

#1の方が言っているように、クラス設計に問題があると思います。 このクラスは「リストの要素」なのか「リスト全体」なのかが あいまいになっています。 提示されたメインの中では「0」を値に持つデータをダミーにして 操作しています。 「リスト全体」のオブジェクトを生成し、以降は「リスト全体」の オブジェクトに対して操作する、と考えることによりダミーは不要になります。 また、firstNodeやlastNodeはインスタンス変数なのでオブジェクトごとに 存在します。 つまりデータひとつひとつに「先頭のデータ」「末尾のデータ」が 存在することになってしまいます。 データとnext、prevをメンバに持つような「リストの要素」クラスと firstNodeやlastNodeをメンバに持つような「リスト全体」クラスに 分けて考えてみてはどうでしょうか? ちなみに、プログラムの問題点ですが、「あるノード」として操作基準 としている「new MyListw(1)」というオブジェクトと、 プログラムの先頭のほうで追加したオブジェクトは別物です。 そのためnode.nextやnode.prevはnullとなっており、操作しても 思ったようにはいきません。 誤ってfirstNode、lastNodeを変更してしまっています。 newで生成するのは「新しい別のオブジェクト」です。 同一のオブジェクトを扱うのであれば変数に格納しておき、 それを指定する必要があります。 (一部変更例) MyListw target1=new MyListw(1); list.insertTail(target1); MyListw target2=new MyListw(2); list.insertAfter(target1, target2); list.insertAfter(target2, new MyListw(3)); 最後に、厳しいようですが#1の方の言うように質問の仕方をもう少し 見直すといいですね。 「うまくいかない」人が「教えて」欲しくて書き込んでいることがほとんどです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「指定したノードの次に新たなノード追加以降からどうしてもうまくできません」とはどういうことでしょうか? まず, どの時点で「うまくできない」のか明確に書いてください. 例えば 「list.insertAfter(new MyListw(1), new MyListw(2)); の次の list.show(); で思ったように表示されない」など, 書きようはあるはずです. さらに, 「どのように」「うまくできない」のかも書いてください. この場合には ・その前でリストがどうなっていて ・どういう動作をするはずで ・どういう結果になっているはずのところが ・実際に得られた結果はどうであったのか くらいでしょうか. あと, タイトルが最悪. そもそも「何か教えてほしいことがある」からこそ質問するはずなので, 「教えて。」というタイトルでは全く相手に伝わりません. 今の場合なら「リストの挿入について」とかなんとか書けるはずです. ただ, 本質的なところだけど, クラスの設計が多分間違っています. クラスMyListw が何を表しているのか, 「簡潔に (できれば一言で)」表現してみてください.

noname#95170
質問者

補足

説明不足ですいません。 指定したノードの次に新たなノード追加を実行すると 9815→98125 になると思ってたんですが、実際には 9815のままなんです。 実行結果がこんな感じです。 最後に追加 1 逆順に表示 1 15 逆順に表示 51 ----------------------------------------- 先頭に追加 815 逆順に表示 518 9815 逆順に表示 5189 ----------------------------------------- 指定したノードの次に新たなノード追加 9815 逆順に表示 21 9815 逆順に表示 32 ----------------------------------------- 指定したノードの前に新たなノード 01 逆順に表示 32 ----------------------------------------- リストからデータを削除 逆順に表示 ----------------------------------------- 先頭のノードを削除 Exception in thread "main" java.lang.NullPointerException at MyListw.deleteHead(MyListwApp.java:70) at MyListwApp.main(MyListwApp.java:169)