Java中使用递归的二叉搜索树

发布于 2024-10-20 17:13:18 字数 535 浏览 2 评论 0原文

我希望有人能给我解释一下我应该如何完成这两种方法。我愿意自己做这项工作,并且不想偷懒。话虽如此,问题来了:

2种方法: 递归地需要

  1. 统计二叉树的节点数,
  2. 统计右孩子的数量

我已经实现了以下代码:

public class IntBSTNode
{

    protected int key;
    protected IntBSTNode left, right;

    public IntBSTNode()
    {
        left = right =null;
    }

    public IntBSTNode(int el)
    {
        this(el, null, null);
    }

    public IntBSTNode( int el, IntBSTNode lt, IntBSTNode rt)
    {
        key = el;
        left =lt;
        right = rt;
    }
}

I am hoping someone can give me an explanation of how I am supposed to finish these two methods. I am willing to do the work myself and am not trying to be lazy. Having said that, here is the problem:

2 methods: Recursively need to

  1. count the number of nodes in a binary tree,
  2. count the number of right children

I have already implemented the following code:

public class IntBSTNode
{

    protected int key;
    protected IntBSTNode left, right;

    public IntBSTNode()
    {
        left = right =null;
    }

    public IntBSTNode(int el)
    {
        this(el, null, null);
    }

    public IntBSTNode( int el, IntBSTNode lt, IntBSTNode rt)
    {
        key = el;
        left =lt;
        right = rt;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半世蒼涼 2024-10-27 17:13:18

http://en.wikipedia.org/wiki/Recursion

要使递归工作,您需要一个基础案例,以及一组减少到基本案例的案例和行动。

为了计算二叉树中的节点数量,我们可以使用“节点不存在”的基本情况,以及“节点确实存在”的其他情况。

对于另一种情况,(节点确实存在)我们将节点数加 1,将树的每个子树(左和右)中的节点数添加到总计数中。我们如何找到子树中的节点数?只需将我们用于第一个节点的相同条件集应用于子节点即可。

通过反复分解树的子节点,我们可以获得树中节点的总数。

举个例子:

     N1
     /\ 
   N2   N3
   /\    \
 N4  N5   N6

让我们调用我们的计数方法 countNodes()。

countNodes 的伪代码

int countNodes(Node parent):
    if parent:
        return 1 + countNodes(parent.left) + countNodes(parent.right)
    else:
        return 0

countNodes 将首先检查您传递给它的节点是否存在。

如果不存在(基本情况),则返回 0 [从逻辑上讲,这是有道理的,因为如果该节点不存在,则其子树中就不存在不存在的节点]

如果该节点存在,您将返回 1 + 中节点数的总和子树。要查找子树中的节点数,我们只需在每个子节点上调用 countNodes() 方法。

在上面的示例树中,我们从 N1 开始。我们看到 N1 存在,所以我们现在需要找到的是:

1 + 左子树中的节点数 + 右子树中的节点数。

N1 的子树是:

  Left         Right
   N2            N3
   /\             \
 N4  N5            N6

我们首先调用 countNodes( ) N2(N1 的左子树)上的方法。

N2 存在,所以现在我们正在寻找

1 + N2 左子树中的节点数 + N2 右子树中的节点数

N2 的子树是:

Left     Right
 N4       N5

在 N4 上调用 countNodes() 我们正在寻找

1 + N4 左子树中的节点数 + N4 右子树中的节点数

N4 的左节点为 null,因此当在 N4 的左节点上调用 countNodes() 时,它将返回 0(基本情况)。

N4 的右侧节点也为 null,因此右侧节点的 countNodes() 也将返回 0

N4 的挂起操作可以完成,并且您有 1 + 0 + 0 (非基本情况返回值)

现在 N2 的挂起操作看起来像

1 + 1 + 节点数右子树

在 N5 上调用 countNodes() 会得到与 N4 相同的值,因此 N2 的返回值变为:

1 + 1 + 1

N2 将 3 返回给 N1待处理操作使其看起来像:

1 + 3 + #nodes in right subtree

# nodes in N3 subtree is:
countNodes() on N3 returns 1 + countNodes->null (base) + countNodes()->N6

# nodes in N6 subtree is
countNodes() on N6 returns 1 + countNodes->null (base) + countNodes()->null (base)
return value = 1

# nodes in N3 subtree is 1 + 0 + 1
returns 2

finally the call on N1's countNodes() can complete with 

1 + 3 + 2

countNodes() on N1 returns 6

要计算树中的所有正确节点,您可以使用以下伪代码:

int countRightNodes(Node parent):
    if !parent:
        return 0

    if has right node:
        return 1 + (# of right nodes in left subtree) + (# of right nodes in right subtree)
    else:
        return (# of right nodes in left subtree)

http://en.wikipedia.org/wiki/Recursion

For recursion to work you need a base case, and a set of cases and actions that reduce towards the base case.

For counting the number of nodes in a binary trees, we can use the base case of "a node does not exists", and other case of "a node does exist".

For the other case, (node does exist) we will add 1 to the count of nodes add the number of nodes in each of the tree's subtrees (left and right) to the total count. How do we find the number of nodes in the subtrees? Simply apply the same set of conditions that we used for the first node to the child nodes.

By repeatedly breaking down the tree's subnodes we can obtain the total number of nodes in the tree

Take for example:

     N1
     /\ 
   N2   N3
   /\    \
 N4  N5   N6

Let's call our counting method countNodes().

pseudocode for countNodes

int countNodes(Node parent):
    if parent:
        return 1 + countNodes(parent.left) + countNodes(parent.right)
    else:
        return 0

countNodes will first check if the node you pass to it exists.

If not (base case) return 0 [logically this makes sense because if the node doesnt exist, there will be no nodes in it's subtree's that dont exist]

If the node exists you will return 1 + the sum of the number of nodes in the subtrees. To find the number of nodes in the subtrees we will just call our countNodes() method on each child node.

In the example tree above we start with N1. We see that N1 exists so what we need to find now is:

1 + # of nodes in the left subtree + # of nodes in the right subtree.

N1's subtrees are:

  Left         Right
   N2            N3
   /\             \
 N4  N5            N6

We start by calling the countNodes() method on N2 (N1's left subtree).

N2 exists so now we are looking for

1 + # of nodes in N2's left subtree + # of nodes in N2's right subtree

N2's subtrees are:

Left     Right
 N4       N5

calling countNodes() on N4 we are looking for

1 + # of nodes in N4's left subtree + # of nodes in N4's right subtree

N4's left node is null so when countNodes() is called on N4's left node it will return 0 (base case).

N4's right node is also null so countNodes() for the right node is also going to return 0

N4's pending operations can complete and you have 1 + 0 + 0 (non-base case return value)

Now N2's pending operation looks like

1 + 1 + # of nodes right subtree

calling countNodes() on N5 results in the same value as N4 so N2's return value has become:

1 + 1 + 1

N2 returns 3 to N1's pending operation to make it look like:

1 + 3 + # nodes in right subtree

# nodes in N3 subtree is:
countNodes() on N3 returns 1 + countNodes->null (base) + countNodes()->N6

# nodes in N6 subtree is
countNodes() on N6 returns 1 + countNodes->null (base) + countNodes()->null (base)
return value = 1

# nodes in N3 subtree is 1 + 0 + 1
returns 2

finally the call on N1's countNodes() can complete with 

1 + 3 + 2

countNodes() on N1 returns 6

To count all the right nodes in a tree you can use the following pseudocode:

int countRightNodes(Node parent):
    if !parent:
        return 0

    if has right node:
        return 1 + (# of right nodes in left subtree) + (# of right nodes in right subtree)
    else:
        return (# of right nodes in left subtree)
淡淡の花香 2024-10-27 17:13:18

递归的意义在于将一个复杂的问题简化,直到它变得微不足道,并使用这个简单问题的解决方案来找到更复杂问题的解决方案,等等,直到可以解决您的实际问题。

在您的情况1)中,复杂的问题是“查找整棵树中的节点数”。但我们可以简化它,说它是 numberOfNodesLeftSubtree + numberOfNodesRightSubtree + 1。然后我们可以写:

public int nbNodes(Node root){
    int count = 1 // our actual node
    if(root.left != null){
        count += nbNodes(root.left);
    }
    if(root.right != null){
        count += nbNodes(root.right);
    }

    return count;
}

就这么简单。

The point of recursion, is to simplify a complicated problem until it is trivial, and use the solution of this trivial problem to find the solution of a more complicated problem, etc, until you can solve your actual problem.

In your case 1), the complicated problem is "Find the number of nodes in the whole tree". But we can simplify this, by saying that it is numberOfNodesLeftSubtree + numberOfNodesRightSubtree + 1. We can then write:

public int nbNodes(Node root){
    int count = 1 // our actual node
    if(root.left != null){
        count += nbNodes(root.left);
    }
    if(root.right != null){
        count += nbNodes(root.right);
    }

    return count;
}

It's that easy.

任性一次 2024-10-27 17:13:18

递归思考需要一些练习,但如果做得好,它几乎看起来很神奇。我们需要计算树中的节点数量,所以让我们想想这意味着什么。考虑任何节点及其子树。该子树中的节点数将等于左子树中的节点数加上右子树中的节点数,再加一(对于相关节点)。因此,如果我们假设我们已经有一个可以对子树中的节点进行计数的方法,那么我们可以对该方法进行两次调用。我们还必须担心基本情况,一旦我们有了递归就可以发挥其魔力。

Thinking recursively takes some practice, but it almost seems magical when done well. We need to count the number of nodes in our tree, so let's think what that means. Consider any node and it's sub-tree. The number of nodes in this sub-tree will be equal to the number of nodes in the left sub-tree plus the number of nodes in the right sub-tree, plus one (for the node in question). So if we assume we already had a method that could count nodes in a sub-tree, we could make two calls to that method. We also have to worry about the base case, and then once we have that recursion can work its magic.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文