首先,我搜索了java中Generic Types的用法,但是我发现的答案过于简单或复杂。所以这是我的确切问题。
我有三个类,分别是PerfectTreeControl,Tree和Entry。
树有
public class Tree<K> { public Entry <K> root;
条目
public class Entry<K> {
public K element;
public Entry<K> parent, left_child, right_child;
public Entry(K element) {
this.element = element;
}
public Entry(K element, Entry<K> left, Entry<K> right) {
left_child = left;
right_child = right;
this.element = element;
}
我试图了解Entry parent和Entry&lt; K&gt;之间的区别。家长吗?我知道K element
可以用作整数,字符串或我想要的任何东西,但同样的事情是针对该对象的吗?我尝试使用没有参数的Entry变量,它只是说Entry是一个原始类型,应该参数化,它仍然可以正常工作。
我的第二个问题是关于检查树是否完美。以下是我到目前为止尝试过的一些代码:
public class PerfectTreeControl {
public static boolean isPerfect(Tree<String> tree) {
Tree t1 = new Tree();
if( t1.isFull( tree.root ) ) {
int depth = t1.height(tree.root);
return t1.everyLeafHasSameDepth(tree.root, depth);
}
else
return false;
}
}
public class Tree<K> {
public Entry <K> root;
public boolean isLeaf(Entry e) {
return e.left_child == null &&
e.right_child == null;
}
public int height(Entry e) {
if( e == null ||
e.left_child == null &&
e.right_child == null )
return 0;
int left = height( e.left_child );
int right = height( e.right_child );
return 1 + Math.max(left, right);
}
public boolean isFull(Entry base) {
if( isLeaf(base) )
return true;
else
if( base.left_child != null && base.right_child != null ) {
return isFull(base.left_child) &&
isFull(base.right_child);
} else {
return false;
}
}
public int depth(Entry e) {
if( e == root ) {
return 0;
} else {
return 1 + depth(e.parent);
}
}
public boolean everyLeafHasSameDepth(Entry base, int depth) {
if( base == null )
return false;
else if(isLeaf(base) )
return depth( base ) == depth;
else {
return
everyLeafHasSameDepth(base.left_child, depth) &&
everyLeafHasSameDepth(base.right_child, depth);
}
}
答案 0 :(得分:3)
更具体地说,在您的类Entry<K>
中,只要您引用K
,Java编译器就会强制所有类型K
的引用实际上都被视为类型{{ 1}}。例如,如果创建类型为K
的对象,则该对象的Entry<String>
成员必须是element
类型,String
成员必须是{{1}类型如果你有一个返回parent
的方法,编译器会认识到返回值为Entry<String>
。如果编译器在这里看到不一致 - 例如,如果您尝试将K
的值设置为String
- 它会抱怨。
请记住,我在上面的示例中描述的质量都是参考您定义的特定member
对象。如果您改为定义Integer
而不更新Entry<String>
类,则会在该新对象中强制执行一致性 - 此时Entry<Integer>
意味着Entry
。
如果创建对象而未指定K
的类型参数,则使用“原始类型”。这可以防止编译器强制执行一致性规则,并假定Integer
的类型为K
。这意味着你必须开始担心铸造,这可能是繁琐的做法。
要检查树是否已满(或“完美”),最直观的方法是递归方法。在这种情况下使用的递归规则是“如果树的孩子是完美的并且具有相同的深度,那么树就是完美的。”