簡體   English   中英

如何返回雙向鏈表並刪除樹的​​葉子?

[英]How to return the doubly linked list and remove leaves of the tree?

我當時正在從事類似SPOJ的任務。 目的是在二叉樹(不一定是BST)中找到葉子,將它們從樹中刪除,並使用相同的結構TreeNode而不是其他導入將它們作為一種雙鏈表返回。 例如,如果從樹中刪除了節點2、4和3,則函數返回列表的firs非null元素:null <-2 <-> 4 <-> 3-> null。 TreeNode有一個值以及左右指針。

我使用了遞歸並取消了葉子,以將其從樹中刪除,並在列表中重新創建了它們。 為了保持向列表末尾添加元素的效率,我保留了指向列表最后一個元素的指針。 這就產生了一個眾所周知的更改傳遞給函數的對象的問題。 這是我的代碼:

public TreeNode getLeaves(TreeNode root)
{
    if(root == null)
        return null;

    TreeNode start = new TreeNode(Integer.MIN_VALUE);
    TreeNode[] end = {start};
    getLeaves(root, start, end);
    return start;
}

private void getLeaves(TreeNode root, TreeNode start, TreeNode[] end)
{
    if(root == null)
        return;

    if(root.left == null && root.right == null)
    {
        addToList(root, start, end);
        root = null;
        return;
    }
    getLeaves(root.left, start, end);
    getLeaves(root.right, start, end);
}

private void addToList(TreeNode element, TreeNode start, TreeNode[] end)
{
    if(end[0].value != Integer.MIN_VALUE)
    {
        TreeNode t = new TreeNode (element.value);
        end[0].right = t;
        t.left = end[0];
        end[0] = t;
    }
    else
    {
        start.value = element.value;
    }
}

從樹中刪除葉子不起作用,但是列表已正確返回。 但是,將“ start” TreeNode的值設置為最小int值而不是使用null引用會讓我很煩,使用數組也是如此。 使用“原子引用”會使IMHO更加混亂。 我非常確定,有一種方法可以通過更優雅的方式(並正確刪除葉子)來實現,可能是通過更改分配開始和結束TreeNodes的方法來實現的。 我的方法和/或對所有工作方式的理解都出了問題。 您能幫我把它變成整潔的代碼並解釋我的壞處嗎?

您的第二個GetLeaves函數中有一個錯誤。 語句root = null; 局部變量 root的值設置為null,但是其父級將保留對葉子的引用。

如果將方法bool isLeaf()TreeNode您的時間會容易得多。 我將您的代碼修改為我認為可能有用的代碼。

private bool isLeaf()
{
    // This method should be in TreeNode
    return left == null && right == null;
}
// Also, TreeNode should have an Add(TreeNode) method

public TreeNode getLeaves(TreeNode root)
{
    if( root == null )  // check if the whole tree is empty
        return null;  // return something relevant here
    else if( root.isLeaf() )
        return root;  //cannot remove this leaf, unfortunately
    TreeNode leaves = new TreeNode()
    getLeaves(root, leaves);
    return leaves;
}
private void getLeaves(TreeNode current, TreeNode leaves)
{
    // current is guaranteed to be non-null and not a leaf itself.
    if( current.left.isLeaf() ) {
        leaves.add(current.left);
        current.left = null;
    } else {
        getLeaves(current.left, leaves);
    }
    if( current.right.isLeaf() ) {
        leaves.add(current.right);
        current.right = null;
    } else {
        getLeaves(current.right, leaves);
    }
}

大衛,你是100%正確的。 感謝您的幫助。 如果有人想知道的話,這是迄今為止我提出的最優雅的解決方案,包括David的改進。 我唯一不確定的是addToList方法應該是靜態的還是在元素的上下文中調用它更合適/更通用。

public TreeNode getLeaves(TreeNode root)
{
    if(root == null)
        return null;

    if(root.isLeaf())
        return root;

    TreeNode[] listEdges = {null, null};
    getLeaves(root, listEdges);
    return listEdges[0];
}

private void getLeaves(TreeNode root, TreeNode[] edges)
{
    if(root == null)
        return;

    if(root.left != null && root.left.isLeaf())
    {
        addToList(edges, root.left);
        root.left = null;
    }

    if(root.right != null && root.right.isLeaf())
    {
        addToList(edges, root.right);
        root.right = null;
    }
    getLeaves(root.left, edges);
    getLeaves(root.right, edges);
}

private static void addToList(TreeNode[] edges, TreeNode element)
{
    if(edges[1] != null)
    {
        edges[1].right = element;
        element.left = edges[1];
        edges[1] = element;
    }
    else
    {
        edges[0] = element;
        edges[1] = edges[0];
    }
}

public boolean isLeaf()
{
    return this.right == null && this.left == null;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM