前提・実現したいこと
Kotlinで双方向連結リストを実装したい。
前提として下記サイトを参考にした。
双方向連結リスト - アルゴリズムとデータ構造 | ++C++; // 未確認飛行 C
発生している問題・エラーメッセージ
kotlinc-jvm.bat ".\BidirectionalLinkedList.kt" -include-runtime -d ".\BidirectionalLinkedList.jar"
一旦、上記でコンパイルが通るよう修正しました。
新たな問題点は3点。(編集前の4点は保留)
(5)(4)とほぼ同義だが、型引数Tの指定方法がよくわからない。とりあえずAny?に変更した。
(6)NodeクラスもBidirectionalLinkedListIteratorクラスもBidirectionalLinkedListにだけ見えるようにしたいが、単純に内部クラスにしてしまうと、~IteratorクラスからNodeクラスが見えない。
(7)IteratorとかIterableの継承方法がよくわからない。
該当のソースコード
Kotlin
1//https://ufcpp.net/study/algorithm/col_blist.html 2 3package Collections; 4 5 6///<summary> 7/// 双方向連結リスト。 8///</summary> 9///<typeparam name = "T">要素の型</typeparam> 10public class BidirectionalLinkedList { 11 12 //#region フィールド 13 14 public val dummy: Node; 15 public var count: Int; 16 17 //#endregion 18 19 //#region 初期化 20 21 public constructor() { 22 this.dummy = Node(null, null, null); 23 this.dummy.Next = this.dummy; 24 this.dummy.Previous = this.dummy; 25 this.count = 0; 26 } 27 28 //#endregion 29 30 //#region プロパティ 31 32 public val First: Node? 33 get() = this.dummy.Next; 34 35 public val Last: Node? 36 get() = this.dummy.Previous; 37 38 ///<summary> 39 /// リストの終端(末尾よりも後ろの番兵に当たるノード)。 40 ///</summary> 41 public val End: Node? 42 get() = this.dummy; 43 44 //#endregion 45 46 //#region 挿入・削除 47 48 ///<summary> 49 /// ノード n の後ろに新しい要素を追加。 50 ///</summary> 51 ///<param name = "e">新しい要素</param> 52 ///<param name = "n">要素の挿入位置</param> 53 ///<returns>新しく挿入されたノード</returns> 54 public fun InsertEAfterN(e: Any?, n: Node?): Node? { 55 val m: Node? = Node(e, n, n?.Next); 56 n?.Next?.Previous = m; 57 n?.Next = m; 58 this.count++; 59 return m; 60 } 61 62 ///<summary> 63 /// ノード n の前に新しい要素を追加。 64 ///</summary> 65 ///<param name = "e">新しい要素</param> 66 ///<param name = "n">要素の挿入位置</param> 67 ///<returns>新しく挿入されたノード</returns> 68 public fun InsertEBeforeN(e: Any?, n: Node?): Node? { 69 val m: Node? = Node(e, n?.Previous, n); 70 n?.Previous?.Next = m; 71 n?.Previous = m; 72 this.count++; 73 return m; 74 } 75 76 ///<summary> 77 /// 先頭に新しい要素を追加。 78 ///</summary> 79 ///<param name = "elem">新しい要素</param> 80 ///<returns>新しく挿入されたノード</returns> 81 public fun InsertFirst(elem: Any?): Node? { 82 return this.InsertEAfterN(elem, this.dummy); 83 } 84 85 ///<summary> 86 /// 末尾に新しい要素を追加。 87 ///</summary> 88 ///<param name = "elem">新しい要素</param> 89 ///<returns>新しく挿入されたノード</returns> 90 public fun InsertLast(elem: Any?): Node? { 91 return this.InsertEBeforeN(elem, this.dummy); 92 } 93 94 ///<summary> 95 /// ノード n 自身を削除。 96 ///</summary> 97 ///<param name = "n">要素の削除位置</param> 98 ///<returns>削除した要素の次のノード</returns> 99 public fun Erase(n: Node?): Node? { 100 if (n == this.dummy) { 101 return this.dummy; 102 } 103 n?.Previous?.Next = n?.Next; 104 n?.Next?.Previous = n?.Previous; 105 this.count--; 106 return n?.Next; 107 } 108 109 ///<summary> 110 /// 先頭の要素を削除。 111 ///</summary> 112 public fun EraseFirst(): Unit { 113 this.Erase(this.First); 114 } 115 116 ///<summary> 117 /// 末尾の要素を削除。 118 ///</summary> 119 public fun EraseLast(): Unit { 120 this.Erase(this.Last); 121 } 122 123 //#endregion 124 125 //#region IEnumerable<T>メンバ 126 127 operator fun iterator() = BidirectionalLinkedListIterator(this); 128 129 //#endregion 130 131} 132 133public class BidirectionalLinkedListIterator(val list: BidirectionalLinkedList) { 134 private var n: Node? = list.First; 135 fun next(): Node? { 136 return n?.Next; 137 } 138 fun hasNext(): Boolean { 139 return n != list.End; 140 } 141} 142 143///<summary> 144/// 連結リストのノード。 145///</summary> 146public class Node { 147 148 //#region フィールド 149 150 private var value: Any?; 151 private var prev: Node?; 152 private var next: Node?; 153 154 //#endregion 155 156 //#region 初期化 157 158 internal constructor(_value: Any?, _prev: Node?, _next: Node?) { 159 this.value = _value; 160 this.prev = _prev; 161 this.next = _next; 162 } 163 164 //#endregion 165 166 //#region プロパティ 167 168 public var Value: Any? 169 get() = this.value; 170 set(value) { 171 this.value = value; 172 } 173 174 /// <summary> 175 /// 前のノード。 176 /// </summary> 177 var Previous: Node? 178 get() = this.prev; 179 internal set(value) { 180 this.prev = value; 181 } 182 183 /// <summary> 184 /// 次のノード。 185 /// </summary> 186 var Next: Node? 187 get() = this.next; 188 internal set(value) { 189 this.next = value; 190 } 191 192 //#endregion 193 194}
試したこと
(1)Kotlinで調べても全然情報が見つからないため、主にjavaで調べたのですが、GetEnumeratorなどの実装例が見つからず断念。
Iteratorを試そうとしたが、現在のNode?の指定方法や初期化が不明なために断念。とりあえずコメントアウト。
(2)他作クラスがどこにあるのかわからず、クラスパス?へ設定できずimportも保留。
(4)Kotlinの和訳リファレンスやネットで使用例などを見る限り、型引数の使い方も間違ってなさそうに見えるがダメらしい。
補足情報(FW/ツールのバージョンなど)
・kotlincは1.3.60
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。