質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

1417閲覧

自作した二分探索木で挿入や検索をしたいのですが行き詰まっています。

karasu116

総合スコア2

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2020/09/30 05:49

編集2020/10/01 04:27

前提・実現したいこと

現在、Javaの勉強に取り組んでいます。

自作した二分探索木でデータの挿入や検索を行いたいです。
どのようにすれば、適切な処理を行うことができるでしょうか?

発生している問題・エラーメッセージ

はじめに、1からnまでの整数をint型の配列arrayにランダムに入れます。
ランダムに並んだ整数を二分探索木の適当な場所に挿入するために自作したメソッドinsert()を
使いたいです。しかし、このinsert()について次のエラーが表示されます。

エラーメッセージ insertに適切なメソッドが見つかりません(int) tree.insert(array[i]); ^ メソッド BinSearchTree.insert(Entry<Integer,Object>)は使用できません (引数の不一致: intをEntry<Integer,Object>に変換できません:) メソッド BinSearchTree.insert(BinSearchTreeNode<Integer,Object>,Entry<Integer,Object>)は使用できません (実引数リストと仮引数リストの長さが異なります) エラー1個

該当のソースコード

メインのクラスです。

Java

1package genericSearch; 2 3import java.util.Comparator; 4import java.util.Iterator; 5import java.util.Random; 6import java.util.Scanner; 7import java.util.Set; 8import java.util.TreeMap; 9import genericSearch.*; 10 11public class Main { 12 13 @SuppressWarnings("resource") 14 public static void main(String[] args) { 15 16 BinSearchTree<Integer, Object> tree = 17 new BinSearchTree<Integer, Object>( 18 new Comparator<Integer>() { 19 public int compare(Integer a, Integer b){ 20 return b - a; 21 } 22 } 23 ); 24 25 int n; 26 Scanner keyboard = new Scanner(System.in); 27 28 System.out.println("#integers: "); 29 n = keyboard.nextInt(); 30 int[] array = new int[n]; 31 for(int i = 0; i < n; i++) { 32 array[i] = i + 1; 33 } 34 Random rand = new Random(); 35 for(int i = 0; i < n; i++) { 36 int j = rand.nextInt(n - i); 37 int temp = array[n - 1 - i]; 38 array[n - 1 - i] = array[j]; 39 array[j] = temp; 40 } 41 42 for (int i = 0 ; i < n ; i++) { 43 //System.out.print(array[i] + " "); 44 tree.insert(array[i]); 45 } 46 System.out.println("") ; 47 48 int m = rand.nextInt(n) ; 49 System.out.println("trying to find " + m + " ..."); 50 if(tree.search(m) != null) { 51 System.out.println("found " + m) ; //結果表示 52 System.out.println("") ; 53 } 54 55 System.out.println("") ; 56 57 /** 58 //木にあるデータのキーを指定順に表示する. 59 Set<Integer> keys = tree.keySet() ; 60 System.out.println("data in sorted order:"); 61 Iterator<Integer> iter = keys.iterator() ; 62 while (iter.hasNext()) { 63 System.out.print(iter.next() + " "); 64 } 65 */ 66 } 67 68}

探索木に対して処理を行うクラスです。

java

1package genericSearch; 2 3import java.util.Comparator; 4import java.util.Iterator; 5import java.util.LinkedList; 6import java.util.List; 7import java.util.Map; 8 9//Kはデータのキーの型,Vはデータの値の型 10public class BinSearchTree<K,V> { 11 private BinSearchTreeNode<K,V> root ; 12 private Comparator<K> comparator ; 13 14 //引数なしのコンストラクタを禁止. 15 @SuppressWarnings("all") 16 private BinSearchTree( ) { } 17 18 //引数ありのコンストラクタ. 19 public BinSearchTree(Comparator<K> comparator) { 20 this.comparator = comparator ; 21 } 22 23 //空の木か否かを判定するメソッド 24 public boolean isEmpty() { 25 return root == null; 26 } 27 28 //この木において指定キーを持つデータを検索するメソッド 29 public V search(K key) { 30 return search(root, key); 31 } 32 33 34 //startを根とする木において指定キーを持つデータを検索するメソッド 35 private V search(BinSearchTreeNode<K,V> start, K key) { 36 //if (start == null) return null ; //木が空の場合 37 38 while(start != null) { 39 if(comparator.compare(key, start.getData().getKey()) == 0){ 40 return start.getData().getValue(); 41 } 42 43 else if(comparator.compare(key, start.getData().getKey()) < 0){ 44 start = start.getLeft(); 45 } 46 else{ 47 start = start.getRight(); 48 } 49 } 50 51 return null; 52 } 53 54 55 //この木において指定キーを持つデータを検索するメソッド 56 public void insert(Map.Entry<K,V> data) { 57 root = insert(root, data); 58 } 59 60 61 //startを根とする木に新しいデータを挿入してから,結果の木を返すメソッド 62 private BinSearchTreeNode<K,V> insert(BinSearchTreeNode<K,V> start, Map.Entry<K,V> data) { 63 //易しい場合:空の木の場合 64 if (start == null) { 65 return new BinSearchTreeNode<K,V>(data) ; 66 } 67 68 while(true) { 69 if(comparator.compare(start.getData().getKey(), data.getKey()) < 0) { 70 if(start.getLeft() == null) { 71 start.setLeft(new BinSearchTreeNode<K, V>(data)); 72 } 73 else { 74 start = start.getLeft(); 75 } 76 } 77 else { 78 if(start.getRight() == null) { 79 start.setRight(new BinSearchTreeNode<K, V>(data)); 80 } 81 else { 82 start = start.getRight(); 83 } 84 } 85 } 86 } 87 88 89 //木から指定のキーを持つデータを削除してから,結果の木を返すメソッド 90 public void delete(K key) { 91 root = delete(root, key); 92 } 93 94 95 //木から指定のキーを持つデータを削除してから,結果の木を返すメソッド 96 private BinSearchTreeNode<K,V> delete(BinSearchTreeNode<K,V> start, K key) { 97 //木が空のとき,そのまま返す 98 if (start == null) return null ; 99 100 if(start.isLeaf()) { 101 return null; 102 } 103 if(start.getLeft() == null) { 104 return start.getRight(); 105 } 106 if(start.getRight() == null) { 107 return start.getLeft(); 108 } 109 else { 110 BinSearchTreeNode<K,V> p = start.getRight(); 111 while(p.getLeft() != null) { 112 p = p.getLeft(); 113 } 114 Map.Entry<K,V> nextBigData = p.getData(); 115 116 start.setRight( delete(start.getRight(), nextBigData.getKey()) ); 117 start.setData(nextBigData) ; 118 return start ; 119 } 120 } 121 122 123 //preorderの順に2分探索木にあるデータをたどるためのメソッド 124 public Iterator<Map.Entry<K,V>> preorderIterator() { 125 return preorder(root).iterator(); 126 } 127 128 //preorderIterator内でしか呼び出されない再帰メソッド 129 private List<Map.Entry<K,V>> preorder(BinSearchTreeNode<K,V> start) { 130 List<Map.Entry<K,V>> list = new LinkedList<Map.Entry<K,V>>() ; 131 if (start == null) return list ; 132 else { 133 list.add(start.getData()) ; 134 list.addAll(preorder(start.getLeft())) ; 135 list.addAll(preorder(start.getRight())) ; 136 return list ; 137 } 138 } 139 140 //inorderの順に2分探索木にあるデータをたどるためのメソッド 141 public Iterator<Map.Entry<K,V>> inorderIterator() { 142 return inorder(root).iterator(); 143 } 144 145 //inorderIterator内でしか呼び出されない再帰メソッド 146 private List<Map.Entry<K,V>> inorder(BinSearchTreeNode<K,V> start) { 147 List<Map.Entry<K,V>> list = new LinkedList<Map.Entry<K,V>>() ; 148 if (start == null) return list ; 149 else { 150 list.addAll(inorder(start.getLeft())) ; 151 list.add(start.getData()) ; 152 list.addAll(inorder(start.getRight())) ; 153 return list ; 154 } 155 } 156 157 //postorderの順に2分探索木にあるデータをたどるためのメソッド 158 public Iterator<Map.Entry<K,V>> postorderIterator() { 159 return postorder(root).iterator(); 160 } 161 162 //postorderIterator内でしか呼び出されない再帰メソッド 163 private List<Map.Entry<K,V>> postorder(BinSearchTreeNode<K,V> start) { 164 List<Map.Entry<K,V>> list = new LinkedList<Map.Entry<K,V>>() ; 165 if (start == null) return list ; 166 else { 167 list.addAll(postorder(start.getLeft())) ; 168 list.addAll(postorder(start.getRight())) ; 169 list.add(start.getData()) ; 170 return list ; 171 } 172 } 173 174 //accessorメソッド 175 public BinSearchTreeNode<K,V> getRoot() { 176 return root ; 177 } 178 public void setRoot(BinSearchTreeNode<K,V> root) { 179 this.root = root ; 180 } 181} 182

java

1package genericSearch; 2 3import java.util.Map; 4 5//Kはデータのキーの型,Vはデータの値の型 6public class BinSearchTreeNode<K,V> { 7 private Map.Entry<K,V> data ; 8 private BinSearchTreeNode<K,V> left, right ; 9 10 //コンストラクタ 11 public BinSearchTreeNode(Map.Entry<K,V> data, BinSearchTreeNode<K,V> left, 12 BinSearchTreeNode<K,V> right) { 13 this.data = data ; 14 this.left = left ; 15 this.right = right ; 16 } 17 18 //葉を作るためのコンストラクタ 19 public BinSearchTreeNode(Map.Entry<K,V> data) { 20 this(data, null, null) ; 21 } 22 23 //葉か否かを判定するメソッド 24 public boolean isLeaf() { 25 return left == null && right == null ; 26 } 27 28 29 //accessorメソッド 30 public Map.Entry<K,V> getData() { 31 return data ; 32 } 33 public BinSearchTreeNode<K,V> getLeft() { 34 return left ; 35 } 36 public BinSearchTreeNode<K,V> getRight() { 37 return right ; 38 } 39 public void setData(Map.Entry<K,V> data) { 40 this.data = data ; 41 } 42 public void setLeft(BinSearchTreeNode<K,V> left) { 43 this.left = left ; 44 } 45 public void setRight(BinSearchTreeNode<K,V> right) { 46 this.right = right ; 47 } 48} 49

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YT0014

2020/10/01 04:20

BinSearchTreeNodeのコードがないので、実証や確認ができません。質問欄を修正して、追記をお願いいたします。
karasu116

2020/10/01 04:28

申し訳ありませんでした。いま追記しましたのでご確認お願いいたします。
YT0014

2020/10/01 05:08

追記ありがとうございます。 修正してエラーが出ているのなら、Mainの更新もご考慮ください。
guest

回答1

0

ベストアンサー

やりたいことが明確になっていないのが原因です。

二分探索木の宣言では、キーがInteger、データがObjectです。
ですが、格納したいのは、intの配列です。

コード上でも、質問欄でも、探索木の要素が不明確です。
intの配列をキーの配列とみなすのならば、データは何でしょうか?

例えば、BinSearchTreeの動作確認のために、int配列の処理を確認したいのでしたら、キー、データともIntegerで宣言して、Map.Entry変数のキーと値の両方に配列の値を設定してから、それをinsert()するという手順が必要かと思います。

コメントに対する追記
まず、Map.Entryは、インターフェースです。実装クラスなどの情報は、javadocをご確認ください。

javadocに記載されている実装クラスを使用されるのなら、コンストラクタ(new クラス名()の形式で呼ばれる処理)の引数2つに、配列の要素を積むことになります。

投稿2020/09/30 06:38

編集2020/09/30 15:56
YT0014

総合スコア1708

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

karasu116

2020/09/30 11:38

回答ありがとうございます。 先日大学の授業で取り扱ったばかりの内容でして、お恥ずかしい話、二分探索木の基本中の基本もわからない状況でございます。 >> BinSearchTreeの動作確認のために、int配列の処理を確認したいのでしたら、キー、データともIntegerで宣言して・・・ BinSearchTree<Integer, Object> tree = new BinSearchTree<Integer, Object> の部分のObjectをIntegerに変えればいいのでしょうか? >> Map.Entiry変数のキーと値の両方に配列の値を設定してから、それをinsert()するという手順が必要かと思います。 具体的な例として一つ上げていただくと大変助かります。
karasu116

2020/09/30 12:33

Map.Entry変数はMap.Entry<Integer, Object> mp; として、mp.setValue(array[i]); tree.insert(mp); のようにしたらこれまでのエラーは消えましたが、mpが初期化されていない旨のエラーがでました。 どのように初期化すればいいでしょうか。
YT0014

2020/09/30 16:13

回答に追記しました。 ただ、初期化は、javaの基本なので言及しておりませんでしたが、最初の回答に、"キーと値の両方に配列の値を設定"と記してあったのですが、なぜsetValue()だけなのでしょうか? また、"自作"とありますが、理解しないままどうやって作成したのでしょうか?サンプルを打ち込んだだけですか? プログラミングを学ぶのなら、仕様などの文言は、一切の曖昧さがない状態まで読み込んでください。また、発する言葉も、精確に使うように心がけてください。
karasu116

2020/10/01 00:50

追記ありがとうございました。 >> まず、Map.Entryは、インターフェースです。実装クラスなどの情報は、javadocをご確認ください。 javadocに記載されている実装クラスを使用されるのなら、コンストラクタ(new クラス名()の形式で呼ばれる処理)の引数2つに、配列の要素を積むことになります。 実装されているクラスはAbstractMap.SimpleEntry, AbstractMap.SimpleImmutableEntryのようでした。 ここで用いるコンストラクタはSimpleEntry()かSimpleImmutableEntry()だと思います。(勘違いでしたら申し訳ないです。) しかし、まずこの段階で両方の説明を読みましたがイマイチ違いが分からない状況です。 とりあえず両方を試してみましたが「シンボルが見つからない」といったエラーが表示されてしまいます。
YT0014

2020/10/01 04:59 編集

以下のコードで、insertが呼ばれるのは確認しました。 AbstractMap.SimpleEntry<Integer, Integer> entry   = new AbstractMap.SimpleEntry<Integer, Integer>(   array[i], array[i]); tree.insert(entry); なお、実際には、insert()は、2要素目以降、無限ループになりますが。
YT0014

2020/10/01 05:06

>しかし、まずこの段階で両方の説明を読みましたがイマイチ違いが分からない状況です。 この場合は、件のインターフェースさえ実装されていれば、クラス本体の中身はどうでも良かったりします。 実際の違いは、後者が、キー、値とも、変更できないようになっていることです。 前者の説明の最初が「キーと値を維持するエントリ。値は、setValue メソッドを使って変更することもできます。」 後者が「不変のキーと値を維持するエントリ。このクラスは setValue メソッドをサポートしません。」 これだけを比べれば、違いが理解できるかと思いますが、いかがでしょう?
karasu116

2020/10/03 09:07

あれから検索、挿入、削除メソッドをいじって格闘し上手く動作するようになりました。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問