2016-10-26 34 views
-1

一般的なバイナリ検索ツリーのコードは次のとおりです。今、それは完璧に実行され、コンパイルされますが、このクラスを終了した後、私が今注目した問題が1つあります。問題は、挿入メソッドがcompareTo()(ノードの要素を比較する場合)を使用してツリーの次のノードをその値に応じてどこに配置するかを決定することです。そして、入力用のインスタンスのために:代わりにこの木を取得するJava - ジェネリック型を比較す​​るにはどうすればよいですか?

1、112、2

1 
    \ 
    2  
    \  
    112 

私が取得し終わると、次のとおりです。

 1 
     \ 
      2 
     /
     112 

おそらく比較は辞書編集的に行われるので、2> 112を参照してください。ここで ツリークラスのコードです:

import java.util.*; 
import java.io.*; 
import java.lang.*; 

public class Tree<T extends Comparable<T>> 
    { private Node<T> root = null; 
    static String S=""; 

    public Tree() 
     {File file=new File("date.in.txt"); 

      try 
      { Scanner input = new Scanner(file); 
      while(input.hasNext()) 
       insert((T)input.next());} 

      catch (FileNotFoundException ex) 
       { System.out.printf("ERROR: %s!\n", ex); } } 


    public void show(){ printLevelOrder(maxDepth()); } 

    public void printLevelOrder(int depth) 
     { for (int i = 1; i <= depth; i++) 
      { System.out.print("Level " + (i-1) + ": "); 
      String levelNodes = printLevel(root, i); 
      System.out.print(levelNodes + "\n"); } } 

    public String printLevel(Node<T> t, int level) 
     { if (t == null) 
      return ""; 
     if (level == 1) 
      return t.element + " "; 
     else if (level > 1) 
      { String leftStr = printLevel(t.left, level - 1); 
      String rightStr = printLevel(t.right, level - 1); 
      return leftStr + rightStr; } 
     else 
      return ""; } 


    int maxDepth(){ return maxDepth2(root); } 

    int maxDepth2(Node<T> node) 
     { if (node == null) 
      return (0); 
     else 
      { int leftDepth = maxDepth2(node.left); 
      int rightDepth = maxDepth2(node.right); 

      if (leftDepth > rightDepth) 
       return (leftDepth + 1); 
      else 
       return (rightDepth + 1); } } 


    public String toString(){ return this.InOrder(); } 


    public String InOrder(){ inOrder2(root); return S; } 

    public void inOrder2(Node<T> root) 
     { if(root != null) 
      { inOrder2(root.left);  
      S=S+root.element+" "; 
      inOrder2(root.right); } } 


    public boolean insert(T element) // I N S E R T M E T H O D 
     { if (isEmpty()) 
      { root = new Node<T>(element); 
      return true; } 

     Node<T> current = root; 
     Node<T> parent;   

     do 
      { parent = current; 

      if (element.compareTo(current.element)<0) 
       current = current.left; 
       else if (element.compareTo(current.element)>0) 
       current = current.right; 
       else 
       return false; } 
      while (current != null); 

     Node<T> node = new Node<T>(element); 


      if (element.compareTo(parent.element)>0 ) 
       parent.right = node; 
      else 
      parent.left = node; 

     return true; } 


    public boolean isEmpty() { return root == null; } 


    private static class Node<T extends Comparable<T>> 
     { Node<T> left = null; 
     Node<T> right = null; 
     final T element; 

     Node(T element) { this.element = element; } } } 

そして、ここでの主な:

今私は研究の少しを行なったし、あちこちで聞かれ、私はの風を得た
import java.util.*; 
import java.io.*; 

public class Main 
    {public static void main(String[]args) 
     {Tree <Double> T=new Tree<>(); } } 

コンパレータと呼ばれるものがありますが、以前はこれを使用していませんでしたが、実装方法はわかりません。今、あなたがこれを修正する方法や追加する/するべきことに対する解決策があれば、私はすべての目と耳の家です。

+0

辞書編集の比較では1 <112となりますので、それは起こっていることではありません。 – user2357112

+2

また、TがIntegerの場合、compareToは辞書編集の比較ではなく、TがStringの場合は、文字列としての整数の格納を停止してT Integerを作成する必要があります。コンパレータは確かに正しいソリューションではありません。 – user2357112

+0

@ user2357112今私は、私の描いた絵が間違っていることに気付きました。私はそれらをやり直しました、それは実際にそうであることが判明したものです。 112 <2というのは、辞書編集の順序と関係があります。 –

答えて

3

あなたのラインinsert((T)input.next());は意味がありません - input.next()Stringですが、Tが、この時点で実数型に関連付けられていない場合であってもTにキャストしています。 Treeを作成する場合、発信者は、例えばnew Tree<Integer>という行を作成することができます。本質的には、insert((Integer)input.next());が壊れています。

あなたの目標は、常にちょうどTreeからジェネリックTタイプを削除し、ちょうどStringを使用し、String Sを含むことTreeに対するものである場合。実際に任意の型をサポートしたい場合は、ファイル読み込み動作をTreeコンストラクタ(たとえば、Tree<String>を返す静的メソッド)に移動する必要があります。例えば

:私はPath代わりのFiletry-with-resourcesパターンを使用し、私は例外を抑制していない、代わりに、発信者(おそらくmain法)が適切に例外を処理する必要があり

public static Tree<String> readFromFile(Path file) throws FileNotFoundException { 
    try (Scanner input = new Scanner(file)) { 
    Tree<String> tree = new Tree<>(); 
    while(input.hasNext()) { 
     tree.insert(input.next()); 
    } 
    return tree; 
    } 
} 

お知らせ(おそらくファイルが存在しないと報告して終了している)。あるいは、catchブロックを追加すると、呼び出し側が例外を処理しなくて済むように、catchブロックを追加します。

catch (IOException e) { 
    throw new RuntimeException("Could not open " + file, e); 
} 


今、私たちはTreeタイプをクリーンアップしてきたことを、あなたの順序の質問は答えることが単純そうです。要素を整数として並べ替える場合は、入力を整数に変換します。

public static Tree<Integer> readIntsFromFile(Path file) throws FileNotFoundException { 
    ... 
    tree.insert(Integer.valueOf(input.next())); 
    ... 
} 

これは、文字列の辞書順ではなく、整数の順序に基づいてツリーを並べ替えます。これは私があなたに提案するものです。それは簡単で、あなたが望むことをします。


あなたは本当にTree<String>をしたいが、あなたは、彼らはあなたが言及としてあなたは、カスタムComparatorを必要とする整数だったかのようにそれらを注文したい場合。 ComparatorTreeのコンストラクタに渡す必要があります。現在element.compareTo(current.element)と呼び出しているcomparator.compare(element, current.element)を呼び出します。

+0

よく、そのすべてが動作しますが、ツリーとして:Tree Tを宣言してから、入力値として二重値を与えるように進めば、insert()メソッドを呼び出すとjava.lang.NumberFormatExceptionが発生します。 –

+0

これは、私がダブルスを処理する関数を含まなかったので、あなたが使っているコードを明確にしている( "うまくいけば"役に立たない)、そして、正確なスタックトレースとエラーメッセージ。 'readIntsFromFile()'を使用したが、戻り値の型と 'insert()'呼び出しの両方で 'Double'に' Integer'を入れ替えた場合、うまく動作するはずです。現在使用しているコードとスタックトレースで質問を編集してください。 – dimo414

+0

私はそれを修正することはできませんでした。ありがとう、芽! –

関連する問題