我正在寻找一种数据结构来表示Java中的层次结构类系统。 例如,我有三个班级,大学,专业,学生,他们的关系如下所示。
我是否可以使用类似路径的表达式查询高效的数据结构? 例如,如果表达式是CMU / cs / jake,那么我得到一个名为jake的学生类实例。据我所知,Trie可以做到这一点,还有其他选择吗?
答案 0 :(得分:1)
如果您的数据适合内存,那么您可以通过在层次结构的每个节点中放置Set
个子项然后遍历集合以确定路径是否有效来实现此目的,例如
class University {
private Set<Major> majors;
}
class Major {
private Set<Student> students;
}
class Main {
// true if the path is valid, else false
public boolean query(University university, Major major, Student student) {
return university.getMajors().contains(major) &&
major.getStudents().contains(student);
}
}
如果您还需要走反向路径(即如果您需要双向层次结构),那么您可以在每个孩子中放置Set
个父母。
这将在平均情况O(d)
中运行,其中d
是层次结构的深度(如果您使用HashSets
,最差情况O(d * lg(n))
n
如果您使用TreeSets
,则为集合的大小。
如果您的数据不适合内存,那么您可能需要考虑使用图形数据库,例如: Neo4j
编辑:假设每个对象都有唯一的名称或其他字符串标识符,您可以通过在每个级别使用Map<String, E>
来使代码更加通用,代价是类型安全。
abstract class Hierarchical<E extends Hierarchical> {
protected final Map<String, E> children;
public boolean query(Queue<String> query) {
String key = query.poll();
if(key != null) {
E value = map.get(key);
if(value != null) {
return query.isEmpty() || value.contains(query);
}
}
return false;
}
}
class University extends Hierarchical<Major> {}
class Major extends Hierarchical<Student> {}
// special case for the bottom of the hierarchy
class Student extends Hierarchical<Hierarchical> {
public Student() {
children = null;
}
@Override
public boolean query(Queue<String> query) {
throw new UnsupportedOperationException("query should never reach this depth");
}
}
class Main {
// true if the path is valid, else false
public boolean query(Hierarchial root, Queue<String> query) {
return root.contains(query);
}
}
这具有相同的运行时间,具体取决于您使用HashMap
还是TreeMap
。查询只包含一个字符串队列;在层次结构的每个级别删除第一个字符串,查询Map
,如果找到则返回子节点,并且查询继续到子节点,直到队列为空(返回true)或节点找不到(返回false)。