二叉树-距离根最远,最右边

时间:2018-12-06 03:25:21

标签: java binary-tree

我有一棵二叉树。在所有最远的节点(我相信树的高度)中,我需要找到那些节点最右侧的节点。

示例1:

      M
     / \
    G   N
   / \   \
  D   H   O
 / \       \
B   F       Q

距离根节点最远的节点中最右边的是'Q'。

示例2:

      M
     / \
    G   N
   / \   \
  D   H   O
 / \       
B   F       

距离根节点最远的节点中最右边的节点是'F'。

我拥有的代码可以获取最深的节点并返回最右边的节点(如果最深的节点没有右边的子节点,则返回左边)。但是后来我遇到了一个问题,其中可能有相同大小的叶子,我不知道如何回溯并比较所有叶子以找到最远的叶子(在这种情况下为“ Q”)

我发现了如何找到树的最大高度,但没有找到如何将其实现到我的代码中

这是我到目前为止所拥有的:

public void find(Node<T> r) {   

    if(r.right == null) { // Are there any children to the right?
        if(r.left.size() > 1) {
            find(r.left); // If not, we go left if there are more than 1
        }

        if(r.left.size() == 1) { //
            rNode = r.left.data;
        }

    }

    if(r.left == null) { // Are there any children to the left?
        if(r.right.size() > 1) {
            find(r.right); // If not, we go right if there are more than 1
        }

        if(r.right.size() == 1) {
            rNode = r.right.data; // If the right is the only node left, pick it as the answer
        }
    }

    if(r.left != null && r.right != null) { // Are there children to the left and right?
        if(r.left.size() == r.right.size()) { // 
            if(r.left.size() == 1) { // If we have 1 child to the right and left, pick the right child
                rNode = r.left.data; // If the left is the only node left, pick it as the answer
            } 
        }

        if(r.left.size() > r.right.size()) { // Are there more to the left?
            find(r.left); // Proceed
        }

        if(r.left.size() < r.right.size()) { // Are there more to the right?
            find(r.right); // Proceed
        }
    } 

}

public int maxDepth(Node<T> r) {

     if(r == null){
         return 0;
     }

     int leftDepth = maxDepth(r.left);
     int rightDepth = maxDepth(r.right);

     return Math.max(leftDepth, rightDepth)+1;     
 }


/**
 * Among all the nodes which are farthest from the root, find the one which is
 * farthest to the right.
 * 
 * @return data value of said node
 */
public T findRightmostLowest() {
    if(root.size() == 1) return root.data;

    find(root);
    return rNode;
}

2 个答案:

答案 0 :(得分:0)

感谢您的帮助,它为我提供了正确的解决方案:

T rNode = null;
boolean found = false;

/**
 * Helper method that recursively finds Rightmost node between 
 * the nodes farthest from the root
 * 
 * @param r
 * @param depth
 * @param i - Our current level of the tree
 */
public void find(Node<T> r, int depth, int i) { 
    if(i == depth && found == false) { // Are we at the answer?
        rNode = r.data; // Dump node into our temporary node

        found = true;   // Change  found to true so we don't enter 
                        // the check a second time.
    }

    if(r.right != null) { // Are there children to the right?
        // If there is, does it lead to one of the farthest leaves?
        if((maxDepth(r.right) + i) == depth) {
            find(r.right, depth, i + 1); 
        }
    }

    if(r.left != null) { // Are there children to the left?
        // If there is, does it lead to one of the farthest leaves?
        if((maxDepth(r.left) + i) == depth) { 
            find(r.left, depth, i + 1);
        }
    }

}

/**
 * Find the height to our tree.
 * 
 * @param r
 * @return
 */
public int maxDepth(Node<T> r) {

     if(r == null){
         return 0;
     }

     int leftDepth = maxDepth(r.left);
     int rightDepth = maxDepth(r.right);

     return Math.max(leftDepth, rightDepth)+1;     
 }


/**
 * Among all the nodes which are farthest from the root, find the one which is
 * farthest to the right.
 * 
 * @return data value of said node
 */
public T findRightmostLowest() {

    rNode = null; // Reset the temporary node
    found = false; // Reset our boolean variable for helper method

    if(root.size() == 1) return root.data; // If tree has only 1 data point, return it

    find(root, maxDepth(root), 1); // Jump into the helper method

    return rNode; 
}

答案 1 :(得分:0)

树问题几乎总是具有与非递归解决方案一样的递归。通常,递归操作要简单得多。如果对于该问题来说还可以,那么它可能看起来像这样:

public static <T> Node<T> getRootFurthest(Node<T> root) {
    return findFurthest(root, 0, new NodeDepth<>()).node;
}

private static <T> NodeDepth<T> findFurthest(Node<T> node, int depth, NodeDepth<T> furthest) {
    if (node == null)
        return furthest;

    // >= - rigth node of equal depth
    // >  - left node of equal depth
    if (depth >= furthest.depth) {
        furthest.node = node;
        furthest.depth = depth;
    }

    findFurthest(node.left, depth + 1, furthest);
    findFurthest(node.right, depth + 1, furthest);

    return furthest;
}

和两个受支持的类声明:

private static final class NodeDepth<T> {

    private Node<T> node;
    private int depth = -1;
}

public static class Node<T> {

    private T val;
    private Node<T> left;
    private Node<T> right;
}