2011-03-04 60 views
1

我一直在嘗試一段時間,以獲得這個圖僞裝成二叉樹工作。目前我正在使用一個傳入根節點的函數和我正在查找的節點的ID。唯一的問題是,根據我的編碼方式,我的一方永遠不能超過3個節點。我相信我只是沒有正確地做遞歸。我一直堅持這一整晚,並不能得到這個。我嘗試過看其他圖表和樹木,但無濟於事。我們沒有使用實際的頂點或其他圖形屬性,但我不能只使用if (x <root.getID())然後root.left,因爲它不能保留,因爲它仍然是一個「圖」深度優先搜索二進制樹/圖中的Java

這是我的非工作搜索算法,如果我使它長到幾個節點,就停止在右側工作。訪問使用HashSet()類。

private Node dfs(Node x, int id) 
{ 
    if (x==null) //base case. Runs into null link 
     return null; 
    if(visited.contains(x.getID())) //visited before 
     return null; 
    visited.add(x.getID()); //don't go below Node again 
    if(id==x.getID()) 
     return x; 
    Node rc = dfs(x.getRightChild(), id); 
    Node lc = dfs(x.getLeftChild(), id); 
    //recursive calls 

    if (lc.getID()==id) 
     return lc; 
    if(rc.getID()==id) 
     return rc; 
    return null; 
} 

我有一個用於打印所有樹的工作代碼,但是我無法在上面的代碼中更改它的密鑰比較。

private String dfsPrint(Node x) //pass in root at top level 
           //returns a String containing all ID's 
{ 
    if (x==null) //base case. Runs into null link 
     return ""; 
    if(visited.contains(x.getID())) //visited before 
     return ""; 
    visited.add(x.getID()); //don't go below Node again 
    String lc = dfsPrint(x.getLeftChild()); //recursive stuffs 
    String rc = dfsPrint(x.getRightChild()); 
    return Integer.toString(x.getID()) + " " + lc + rc; 
} 

謝謝你的幫助。

編輯:我想我會擴展我在做什麼。我必須有一個makeRight或makeLeft函數放入一個新的節點,然後一個現有的節點將它放在它的左邊或右邊。 這是。其中搜索是調用私有dfs的公共方法。

Node search(int id) // calls private dfsSearch() returns null or a ref to 
        // a node with ID = id 
{ 
    int ID = id; 
    Node x= dfs(root, ID); 
    return x; 
} 


void ML(int x, int y) // ML command 
{ 
visited.clear(); 
Node temp = new Node(y, null, null); 
Node current = search(x); 
current.putLeft(temp); 

} 

void MR(int x, int y)//MR command 
{ 
visited.clear(); 
Node temp = new Node(y, null, null); 
Node current = search(x); 
current.putRight(temp); 

} 

取決於如何訂購的遞歸函數如果LC和RC陳述,樹的不同側面被遞歸回升至基本情況,這是什麼讓我承擔DFS方法是什麼是錯的。這是請求的節點類。

class Node { 
private int ID; //ID of the Node. Distinct 
private Node leftChild; 
private Node rightChild; 

Node(int identification)//constructor 

{ 
    ID = identification; 
} 
Node(int identification, Node lt, Node rt) //constructor 

{ 
ID = identification; 
leftChild = lt; 
rightChild = rt; 

} 

int getID() 

{ 
    return ID; 
} 

Node getLeftChild() 
    { 
      return leftChild; 
    } 
Node getRightChild() 
{ 
    return rightChild; 
} 
void putLeft(Node lt) 
{ 
    leftChild = lt; 
} 
void putRight (Node rt) 
{ 
    rightChild = rt; 
} 

}

+0

遞歸邏輯本身應該工作得很好,即使您檢查lc.getId()== id和co是相當混淆。函數唯一的返回值是具有正確id或null的節點。你的問題似乎在別的地方。也許包括你的Node類?此外,如果它是一個二叉樹(因爲它只有兩個孩子),你不需要散列映射,但這也不應該是問題 - 儘管我們需要確保實現。 – Voo 2011-03-04 16:02:40

+0

我編輯了原文,所以只需告訴我你是否需要其他東西。再次感謝您的幫助。 – Scott 2011-03-04 16:17:40

回答

0

dfs方法返回在幾種情況下空。當您嘗試致電getId()這樣的返回值時,您應該會發生異常。你不是嗎?

+0

是的,這是正確的。我得到預期的nullPointerException,但我真的不確定如何測試它,因爲我遇到的函數會生成一個節點,然後將其設置爲已存在節點的左側或右側子節點。我想我只是沒有看到遞歸是如何工作的,因爲如果這個工作正常的話,我使用的輸入都不應該是空的。編輯:我可以確認我打的空是在基本情況下。 – Scott 2011-03-04 15:45:57

1

你可以簡化代碼。我不認爲你需要'身份證'。這個怎麼樣?

private dfs(Node x, int id) { 
    if (x==null) { //base case. Runs into null link 
     return; 
    } 
    if(visited.contains(x)) { //visited before 
     return; 
    } 
    visited.add(x); //don't go below Node again 
    dfs(x.getRightChild()); 
    dfs(x.getLeftChild()); 
} 
+0

那麼,我正在尋找傳入方法ID的節點,所以如果我擺脫了ID,我只是無意中遍歷它,我認爲 – Scott 2011-03-04 15:36:17

+0

沒問題,但是您可以插入: 如果(ID == X。getID()){ return x; } – alvi 2011-03-04 16:29:17

+0

我可以把它弄到的簡單方法是私有節點dfs(節點x,int id) if(x == null){//基本情況。運行成爲空鏈接 返回null; } if(visited.contains(x)){// 之前訪問的返回null; } visited.add(x); //不要再次低於節點 dfs(x.getRightChild(),id); dfs(x.getLeftChild(),id); if(id == x.getID()) return x; 返回null;這也不起作用。我做錯了嗎? – Scott 2011-03-04 17:15:02