学習中のJavaテキストで線形リストについての章があり、その中で
「コパレータcによって互いに等しいとみなすことのできる全ノードを削除する以下のメソッドを作成せよ。
void purge(Comparator<? super E> c)」
という課題がありました。自分でメソッドを作成したのですが、上手く動かないので原因を教えてください。
Java
10. //purgeメソッド以外はテキストに載っていた線形リストを表すクラスです。 21.//purgeメソッドが自分で作ったクラス、purge2メソッドが模範解答です。 32.//ノード 43.class Node<E> { 54. private E data; // データ 65. private Node<E> next; // 後続ポインタ(後続ノードへの参照) 76. 87. // コンストラクタ 98. Node(E data, Node<E> next) { 109. this.data = data; 1110. this.next = next; 1211. } 1312. } 1413.//線形リストクラス 1514.public class LinkedList<E> { 1615. private Node<E> head; // 先頭ノード 1716. private Node<E> crnt; // 着目ノード 1817. 1918. // コンストラクタ 2019. public LinkedList() { 2120. head = crnt = null; 2221. } 2322.//先頭にノードを挿入 2423.public void addFirst(E obj) { 2524. Node<E> ptr = head; // 挿入前の先頭ノード 2625. head = crnt = new Node<E>(obj, ptr); // ノードのデータはobj,後続ポインタの参照先は挿入前の先頭ノード 2726. } 2827.//先頭ノードを削除 2928.public void removeFirst() { 3029. if (head != null) { // リストが空でなければ 3130. head = crnt = head.next; 3231. } 3332. } 3433.//ノードpを削除 3534.public void remove(Node<E> p) { 3635. if (head != null) { 3736. if (p == head) // pが先頭ノードであれば 3837. removeFirst(); // 先頭ノードを削除 3938. } else { 4039. Node<E> ptr = head; 4140. 4241. while (ptr.next != p) { 4342. ptr = ptr.next; 4443. if (ptr == null) { 4544. return; // pはリスト上に存在しない 4645. } 4746. } 4847. ptr.next = p.next; 4948. crnt = ptr; // 削除したノードの先行ノードを参照先とする 5049. } 5150. } 5251.// コンパレータcによって互いに等しいとみなすことのできる全ノードを削除する 5352.public void purge(Comparator<? super E> c) { 5453. Node<E> ptr1 = head; // 比較対象1 5554. Node<E> ptr2; // 比較対象2 5655. Node<E> temp; // 5756. int counter = 0; 5857. 5958. while (ptr1.next != null) { 6059. ptr2 = ptr1.next; 6160. while (ptr2 != null) { 6261. if (c.compare(ptr1.data, ptr2.data) == 0) { 6362. counter++; 6463. temp = ptr2.next; 6564. remove(ptr2); //ここでptr2が削除されない 6665. ptr2 = temp; 6766. } else if (ptr2 != null) { 6867. ptr2 = ptr2.next; 6968. } 7069. } 7170. temp = ptr1.next; 7271. if (counter >= 1) { 7372. remove(ptr1); //ptr1が削除されるときとされない時がある。 7473. } 7574. ptr1 = temp; 7675. counter = 0; 7776. } 7877. //模範解答 7978.public void purge2(Comparator<? super E> c) { 8079. Node<E> ptr = head; // 比較用1 8180. while (ptr != null) { 8281. int count = 0; 8382. Node<E> ptr2 = ptr; // 比較用2 8483. Node<E> pre = ptr; 8584. 8685. while (pre.next != null) { 8786. ptr2 = pre.next; 8887. if (c.compare(ptr.data, ptr2.data) == 0) { 8988. pre.next = ptr2.next;// ptr2はどこからも参照されなくなり削除される 9089. count++; 9190. } else { 9291. pre = ptr2; 9392. } 9493. } 9594. if (count == 0) { 9695. ptr = ptr.next; 9796. } else { 9897. Node<E> temp = ptr; 9998. remove(ptr); 10099. ptr = temp.next; 101100. } 102101. } 103102. crnt = head; 104103. } 105104. // 末尾にノードを挿入 106105. public void addLast(E obj) { 107106. if (head == null) { // リストが空であれば 108107. addFirst(obj); // 先頭に挿入 109108. } else { 110109. Node<E> ptr = head; 111110. // 末尾ノードを見つける処理 112111. while (ptr.next != null) { 113112. ptr = ptr.next; 114113. } 115114. ptr.next = crnt = new Node<E>(obj, null); 116115. } 117116. } 118117.// 全ノードを表示 119118. public void dump() { 120119. Node<E> ptr = head; 121120. while (ptr != null) { 122121. System.out.println(ptr.data); 123122. ptr = ptr.next; 124123. } 125124. } 126125. 127130. public static void main(String[] args) { 128131. LinkedList<Data> list = new LinkedList<Data>(); 129132. Data d1 = new Data(1, "sayama"); 130133. Data d2 = new Data(2, "aki"); 131134. Data d3 = new Data(3, "sayama"); 132135. Data d4 = new Data(4, "akagi"); 133136. Data d5 = new Data(5, "sayama"); 134137. list.addFirst(d1); 135138. list.addLast(d2); 136139. list.addLast(d3); 137140. list.addLast(d4); 138141. list.addLast(d5); 139142. System.out.println(Data.NAME_ORDER.compare(d1, d3)); 140143. list.dump(); 141144. System.out.println("名前でパージします"); 142145. list.purge(Data.NAME_ORDER); 143146. System.out.println(); 144147. list.dump(); 145148. } 146149. } 147
上手く動かない原因は、64行目と72行目のremoveメソッドで削除したいノードを削除できていないからと思っています。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/08/13 07:18