2013-05-31 41 views
0

我剛剛實現了BFS和DFS算法。Java BFS算法 - 試圖在JPanel上繪製節點

我的最終目標是將算法動畫到一個JPanel ......

但是首先我想繪製屏幕上的節點在各自的親子關係:

enter image description here

到目前爲止,我已經能夠實現:

enter image description here

我的塗料成份如下:

public void paintComponent(Graphics g) {   
    ArrayList<Nodes> nodePrintList = new ArrayList<Nodes>();  
    g.setColor(Color.WHITE); 
    g.fillRect(0, 0, width, height); 

    int x = 50, y = 50; 

    //if currentNode has no more children, move to next node 
    g.setColor(Color.GREEN); 
    g.fillRect(x, y, getRootNode().getWidth(), getRootNode().getHeight()); 

    g.setColor(Color.BLACK); 
    g.drawString(getRootNode().getValue(),x+9, y+16); 

    nodePrintList = getChildren(rootNode); 
    x-=30; 
    for (Nodes n : nodePrintList) {  
     System.out.println("\nChildren of " + rootNode.getValue() + ": " + n.getValue()); 
     g.setColor(Color.BLUE); 
     g.fillRect(x, y+30, n.getWidth(), n.getHeight()); 
     g.setColor(Color.WHITE); 
     g.drawString(n.getValue(),x+9, y+45); 
     x+=30; 
    } 

} 

其中通過調用getChildren(Nodes n)獲取該父列表,當前兒童:

//need to pass a new index to getChildren once current node has no more children 
public ArrayList<Nodes> getChildren (Nodes n) { 
    ArrayList<Nodes> childrenList; 
    childrenList = new ArrayList<Nodes>(); 
    int index = nodeList.indexOf(n); 
    int col = 0; 
    while (col < size) { 
     if (adjMatrix[index][col] == 1) { 
      childrenList.add(nodeList.get(col)); 
     } 
     col++; 
    } 
    return childrenList; 
} 

問題:

現在我m硬通過rootNode到getChildren(Node n) ...所以它會返回所有正確的節點...但我需要通過下一個節點,一旦當前節點沒有更多的孩子和李t已經被退回......但我正在努力如何去做。

如果我能夠一次通過下一個節點,當前節點沒有更多的孩子可以輸出,我應該得到我正在尋找的表示。

謝謝!


更新的代碼:

我已經嘗試遞歸遍歷樹和畫出來的節點...

控制檯輸出是正確的......

Children of A: B 
Children of A: C 
Children of A: D 
Children of B: E 
Children of B: F 
end 

但我畫他們的方式根本不是很動態......我爲每個索引有效地添加了一個「層」......然後在它們之間的邊緣

enter image description here

下面是一個使用我的遞歸實現指數:

public void paintComponent(Graphics g) { 
    g.setColor(Color.BLACK); 
    g.fillRect(0, 0, width, height); 

    //paint initial rootNode 
    g.setColor(Color.GREEN); 
    g.fillRect(rootNode.getX(), rootNode.getY(), rootNode.getWidth(), rootNode.getHeight()); 
    g.setColor(Color.black); 
    g.drawString(rootNode.getValue(), rootNode.getX()+8, rootNode.getY()+17); 

    paintComponent(g, 0, new ArrayList<Nodes>()); 
} 

//paint children 
public void paintComponent(Graphics g, int index, ArrayList<Nodes> nodePrintList) { 
    Nodes currNode = nodeList.get(index); 
    nodePrintList = getChildren(currNode); 

    x = currNode.getX(); 
    y = currNode.getY(); 

    //tier 1 
    if (index == 0 && !nodePrintList.isEmpty()) { 
     y += 50; 
     x -= 100; 
     color = Color.CYAN; 
    }//tier 2 
    else if (index == 1 && !nodePrintList.isEmpty()) { 
     y += 100; 
     x -= 130; 
     color = Color.YELLOW; 
    } 
      //and would need to keep adding logic for all indices... 

    //base case: no more children 
    if (nodeList.indexOf(currNode)==nodeList.size()-1 && nodePrintList.isEmpty()) { 
     System.out.println("\nend"); 
    } 
    else {   
     //loop through and print all children of node n 
     for (Nodes child : nodePrintList) { 
      g.setColor(color); 
      System.out.print("\nChildren of " + currNode.getValue() + ": " + child.getValue()); 
      g.fillRect(x+=50, y, child.getWidth(), child.getHeight()); 

      //write which node it is 
      g.setColor(Color.black); 
      g.drawString(child.getValue(), x+8, y+17); 

      //add red edge between parent-child 
      g.setColor(Color.red); 
      g.drawLine(currNode.getX()+10, currNode.getY()+25, x+10, y-2); 

     } 
     paintComponent(g, ++index, new ArrayList<Nodes>()); 
    } 
} 

你可以看到,紅色邊緣適當地從父A連接到其子B, C, D,但紅邊不會從連接B給其子女EF

請任何幫助!

+2

您需要編寫將遞歸遍歷樹的例程。 –

+0

@RomanC請參閱上文。我用我的遞歸解決方案更新了代碼。我遇到連接邊緣的問題。 – Growler

回答

1

這裏有一個辦法做到這一點遞歸:

public void paintComponent(Graphics g) {   
    paintComponent(g, rootNode) 
} 

public void paintComponent(Graphics g, Nodes curRoot) {   
    ... 
    nodePrintList = getChildren(curRoot); 
    for (Nodes n : nodePrintList) {  
     System.out.println("\nChildren of " + rootNode.getValue() + ": " + n.getValue()); 
     ... 
     paintComponent(g, n); 
    } 
} 

但是,你必須與x和y染指座標每次你去下/上樹的時候,所以你記得你畫你的最後在樹的第n層。

哦,從上面的圖形中我看到在你的圖中,一個子節點可以有多個父母(F有多個父母),這使得整個佈局方式更難,因爲你必須記住,如果一個節點有已經繪製完成(如果你想繪製箭頭......)。

+0

或者讓節點自己繪製一個箭頭並將箭頭指向他們孩子的位置。 – arynaq

+0

@rli請參閱上文。我遇到連接邊緣的問題... – Growler