绘制树状图 - 如何组织存储阵列?

时间:2012-04-01 16:51:49

标签: java graph tree pseudocode graph-algorithm

这个问题通常与语言无关(尽管重要的是,我使用的是Java / Processing)。我需要使用一些数据库输出绘制一个树状图。规则很简单:

图表只有一个Root。 每个节点可以有几个子节点,但只有一个父节点。

我无法绕过如何向绘图功能提供数据。我从(它的Rails / MySQL)获取数据的数据库具有以下结构(我使用伪代码来避免不必要的自引用has_many:通过细节):

Graph
 has_many :nodes

Node
 has_many :siblings
 has_one :parent
 has_many :children

问题是 - 我应该如何组织我将节点信息放入的数组以及如何遍历该数组?算法的伪代码会很棒。

如果您发现答案发生时缺少某些信息,请告诉我,我很乐意扩展问题/添加数据。

P.S。我不是在寻找可以为我绘制图形的一些框架/服务的建议,我实际上需要使用我当前的工具来做到这一点。

谢谢!

编辑:

这就是我现在绘制图形的方法......它从['0root','2child',2child2','4child_child']这样的数组中逐个接受,并重构树,假设if(int)前缀数组的下一个元素的大小是2,它是一个孩子,如果它小于2,则它是一个级别(父级的兄弟)。相对于兄弟姐妹的位置是根据数组中具有相同前缀的元素总数来计算的。我想知道是否有更优雅的方法来做到这一点......?

Graph(){         wordList = new ArrayList();         nodeList = new ArrayList();         sibList = new ArrayList();       }

  Integer sibNumber(int idx<char>) {
    Map<Integer, Integer> sibCount = new HashMap<Integer, Integer>();
    for (Integer sibling: sibList) {
      Integer count = sibCount.get(sibling);
      sibCount.put(sibling, (count==null) ? 1 : count+1);
    }
    Integer result = sibCount.get(idx);
    return result;
  }


  void update(String wrd) {
    wordList.add(wrd);

    String word = wrd;
    String[][] m = matchAll(wrd, "(\\d*)");
    int index = (int) m[0][0];
    char number = (char) index;
    sibList.add(index);
//    println(wrd);
    word = word.replaceAll(number,"");
    Integer siblingsNum = sibNumber(index);
    if (sibList.size()>=2) {
      lastIndex = sibList.get(sibList.size()-2);
      int indexDiff = index-lastIndex;
      if (indexDiff != 0) {
        for (int i=sibList.size()-1; i>0; i--) {
          if (index-sibList.get(i) == 2) {
            parNode = nodeList.get(i);
            break;
          }
        }
      }
    }
    if (index == 2) {
      parNode = nodeList.get(0);
    }

    node = new Node(word, index, siblingsNum, parNode);
    nodeList.add(node);

  }

  void clean() {
    nodeList = new ArrayList<Node>();
    sibList = new ArrayList<Integer>();
  }


  void display() {
    for (int i = 0; i < nodeList.size(); i++) {
      nd =  nodeList.get(i);

      if (nd.parent != null) {

        stroke(255, 0, 0);
        VerletSpring2D spring=new VerletSpring2D(nd.origin,nd.parent.origin,80,0.01);
        physics.addParticle(nd.origin);
        physics.addSpring(spring);
        line(nd.origin.x+nd.w/2, nd.origin.y, nd.parent.origin.x+nd.w/2, nd.parent.origin.y+nd.parent.h);
      }
      nd.display();
    }
  }
}

1 个答案:

答案 0 :(得分:0)

你必须使用数组吗?这个问题的自然解决方案是实现一个'Node'类,它引用了子节点。这适用于递归算法,允许您(例如)查找特定节点。 然后,您需要开始的只是对根节点的引用。

public class Node {
  private Node parent;
  private List<Node> children;

  public Node findNode(String nodeName) {
    // Is it this node?
    // Iterate through all child nodes, calling findNode on each
  }
}