简体   繁体   English

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

[英]Hierarchy data structure wih efficient query algorithm

I am looking for a data structure to represent hierarchy class system in Java. 我正在寻找一种数据结构来表示Java中的层次结构类系统。 For example, I have three class, University,Major,Student, and their relationship looks like below. 例如,我有三个班级,大学,专业,学生,他们的关系如下所示。 在此处输入图片说明

Is there a efficient data structure that I can query with a path-like expression? 是否可以使用类似路径的表达式查询有效的数据结构? For example, if the expression is CMU/cs/jake,then I get a instance of student class whose name is jake. 例如,如果表达式为CMU / cs / jake,则得到一个名为jake的学生类实例。 As far as I know, the Trie could do this, is there any other option? 据我所知,特里可以做到这一点,还有其他选择吗?

If your data fits into memory then you can implement this by putting a Set of children in each node of the hierarchy and then walking the sets to determine if the path is valid, for example 如果您的数据适合内存,则可以通过在层次结构的每个节点中放置一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);
  }
}

If you also need to walk the reverse path (ie if you need a bidirectional hierarchy) then you can put a Set of parents in each child. 如果您还需要走相反的道路(即,如果您需要双向层次结构),则可以在每个孩子中放置一Set父母。

This will run in average case O(d) where d is the depth of the hierarchy if you use HashSets , and in worst case O(d * lg(n)) where n is the size of the sets if you use TreeSets . 这将在平均情况运行O(d)其中d是如果你使用的层次结构的深度HashSets ,而在最坏的情况下O(d * lg(n))其中n是集合的大小,如果你使用TreeSets

If your data doesn't fit into memory then you may want to consider using a graph database, eg Neo4j . 如果您的数据不适合内存,那么您可能要考虑使用图形数据库,例如Neo4j


Edit: You can make the code more generic at the cost of type safety by using Map<String, E> at each level, assuming that each object has a unique name or some other string identifier. 编辑:可以通过在每个级别使用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);
  }
}

This has the same runtime depending on whether you use a HashMap or TreeMap . 这具有相同的运行时,具体取决于您使用的是HashMap还是TreeMap The query only consists of a queue of strings; 该查询仅由字符串队列组成; at each level of the hierarchy the first string is removed, the Map is queried and the child node is returned if found, and the query proceeds on to the child node until the queue is empty (return true) or a node isn't found (return false). 在层次结构的每个级别上,删除第一个字符串,查询Map并返回子节点(如果找到),然后查询继续进行到子节点,直到队列为空(返回true)或未找到节点(返回假)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM