这是通用二叉搜索树的代码。现在,它运行和编译完美,但有一个我现在只注意到的问题,在我完成这个课程之后。问题是insert方法使用compareTo()(当比较节点'元素时)来决定将下一个节点放在树中的位置根据它的'值。例如输入:
1,112,2
而不是获取此树:
1
\
2
\
112
我最终获得的是:
1
\
2
/
112
因为可能以字典方式进行比较,所以它看到2> 112。
这里是Tree类的代码:
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 :(得分:3)
您的第insert((T)input.next());
行没有意义 - input.next()
是String
,但您将其投放到T
,即使T
不是Tree
此时与真实类型无关。例如,在构建new Tree<Integer>
调用者时,可以说insert((Integer)input.next());
使这一行显然是Tree
,这就是它。
如果您的目标是String
始终包含T
,请从Tree
中删除通用String
类型,然后使用Tree
。如果您确实想要支持任意类型,则需要将文件读取行为移出Tree<String>
构造函数(例如,转换为返回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;
}
}
的静态方法)。
例如:
File
请注意,我使用Path
代替main
try-with-resources模式,并且我没有抑制异常,而是调用者(可能是catch (IOException e) {
throw new RuntimeException("Could not open " + file, e);
}
方法)应该正确处理异常(可能通过报告文件不存在和退出)。或者像这样添加一个catch块:
Tree
会避免强制调用者处理异常。
现在我们已经清理了public static Tree<Integer> readIntsFromFile(Path file) throws FileNotFoundException {
...
tree.insert(Integer.valueOf(input.next()));
...
}
类型,您的订购问题可能更容易回答。如果您打算将元素排序为整数,请将输入转换为整数,例如
Tree<String>
这将根据整数排序对树进行排序,而不是字符串的字典排序。这就是我建议你做的。它很简单,可以做你想要的。
如果你真的想要一个Comparator
,但是你想要将它们命名为,就像它们是整数一样,你需要一个自定义的Comparator
,正如你所提到的那样。然后,您需要将Tree
传递给comparator.compare(element, current.element)
的构造函数,然后拨打当前呼叫element.compareTo(current.element)
的{{1}}。