层次结构数据结构具有高效的查询算法

时间:2015-06-11 03:14:05

标签: java algorithm data-structures

我正在寻找一种数据结构来表示Java中的层次结构类系统。 例如,我有三个班级,大学,专业,学生,他们的关系如下所示。 enter image description here

我是否可以使用类似路径的表达式查询高效的数据结构?  例如,如果表达式是CMU / cs / jake,那么我得到一个名为jake的学生类实例。据我所知,Trie可以做到这一点,还有其他选择吗?

1 个答案:

答案 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)。