当前位置: 首页 > 知识库问答 >
问题:

Java-二进制家族树-找不到节点

商夜洛
2023-03-14

我正在做一项作业,它要求我输入并显示一个家谱,首先将它转换成一个二叉树--孩子在左边,兄弟在右边。我了解树,遍历树,以及如何使用pre-,in-,和post-order方法搜索某些节点。

我已经编写了代码来插入一个新节点,查找一个节点,并打印整个树,但是我的findNode方法不能正常工作。我需要它使用预购搜索树,并返回它正在寻找的节点。目前,递归方法使它一直到左下角(最小的子节点)和最小的子节点的右下角(最小的兄弟节点),但它从来没有返回到我从其调用的原始节点--因此中断了递归。

下面是我的家族树和主类的代码:

public class FamilyTree
{
Node root;

// Initialize tree
public FamilyTree()
{
    root = null;
}


// --------------------------------------------------------------
// This method inserts a new family member into the tree.
// It takes two parameters - the parent who the new node should
// be inserted under, and the name of the new member being added.
// --------------------------------------------------------------

public void insertNode(String par, String name)
{
    Node parent, current;
    Node newMember = new Node(name);

    // If tree is empty, then the new member becomes the root
    if(root == null)
        root = newMember;


    // If adding a sibling to the root, insert to root's right child
    else if(par == "")
    {
        // Check if root's sibling is empty
        if(root.rightChild == null)
            root.rightChild = newMember;


        // Traverse root's siblings until end, then insert at end
        else
        {
            current = root;

            while(current.rightChild != null)
                current = current.rightChild;

            current.rightChild = newMember;
        }
    }

    else
    {
        // Find the parent where we will insert under
        parent = findNode(par, root);

        System.out.println("parent is = " + parent);
        System.out.println("newMember is = " + newMember + "\n");

        // If that parent doesn't exist, print error msg
        if (parent == null)
            System.out.println("Parent doesn't exist");


        // If parent does exist, but has no left child,
        // then the new member becomes left child
        else if(parent.leftChild == null)   
            parent.leftChild = newMember;


        // If parent already has a left child, then traverse
        // to the end of it's left children and insert node
        else
        {
            current = parent.leftChild;

            while(current.rightChild != null)
                current = current.rightChild;               

            current.rightChild = newMember;
        }   
    }
}


// ------------------------------------------------------------
// This method recursively finds a node in the family tree,
// given the name of the node to look for, and the tree.
// It is run pre-order, and, if found, returns the node
// ------------------------------------------------------------

public Node findNode(String name, Node localTree)
{
    Node current = localTree;

    // Visit the node
    if(current.name == name)
        return current;

    // Pre-order - go left
    if(current.leftChild != null)
    {
        System.out.println("going left to " + current.leftChild);
        return findNode(name, current.leftChild);
    }

    // Pre-order - go right
    if(current.rightChild != null)
    {
        System.out.println("going right to " + current.rightChild);
        return findNode(name, current.rightChild);
    }


    return null;
}

// ------------------------------------------------------------
// This method prints the family tree, given a parent name
// and a tree to print from. It will attempt to find the parent
// node with the given name, then print the entire tree 
// (all children and grandchildren) from that point.
// ------------------------------------------------------------

public void printTree(String par, Node localTree)
{
    Node parent, current;

    // Find the parent to start printing from
    parent = findNode(par, root);
    System.out.println("parent= " + parent);

    // If parent doesn't exist, print error msg
    if (parent == null)
        System.out.println(par + " doesn't exist.");

    else
    {
        current = localTree;

        System.out.println(current);

        if(current.leftChild != null)
            printTree(par, current.leftChild);

        else if(current.rightChild != null)
            printTree(par, current.rightChild);
    }

}

public class Node
{
    Node leftChild, rightChild;
    String name;

    public Node(String n)
    {
        leftChild = null;
        rightChild = null;
        name = n;
    }

    public String toString()
    {
        return name;
    }
}

}

public class Main
{
public static void main (String[] args)
{
    FamilyTree myTree = new FamilyTree();

    myTree.insertNode("", "Grandma Marx");
    myTree.insertNode("", "Great-Aunt Peggie");
    myTree.insertNode("", "Great-Aunt Katherine");
    myTree.insertNode("Grandma Marx", "Aunt Sarah");
    myTree.insertNode("Grandma Marx", "Aunt Tory");
    myTree.insertNode("Grandma Marx", "Uncle Frank");
    myTree.insertNode("Grandma Marx", "Uncle Charles");
    myTree.insertNode("Grandma Marx", "Mom");       

    myTree.insertNode("Aunt Sarah", "Morgan");
    myTree.insertNode("Aunt Sarah", "Tommy");
    myTree.insertNode("Aunt Sarah", "Austin");
    myTree.insertNode("Aunt Sarah", "Luke");

    myTree.insertNode("Aunt Tory", "Tim");

    myTree.insertNode("Mom", "Barret");
    myTree.insertNode("Mom", "Jeremy");
    myTree.insertNode("Mom", "Elliot");


    //myTree.printTree("Grandma Marx", myTree.findNode("Grandma Marx", myTree.root));
}

}

共有1个答案

公羊渝
2023-03-14

问题在于您过早地从搜索中返回:

public Node findNode(String name, Node localTree)
{
...
    // Pre-order - go left
    if(current.leftChild != null)
    {
        System.out.println("going left to " + current.leftChild);
        return findNode(name, current.leftChild); // <===== HERE!
    }
...
}

这会导致函数在遍历左子树后结束,即使结果为null,即未找到节点。

来点这样的怎么样:

public Node findNode(String name, Node localTree)
{
    Node current = localTree;

    // Visit the node
    if(current.name.equals(name))
        return current;

    // Pre-order - go left
    if(current.leftChild != null)
    {
        System.out.println("going left to " + current.leftChild);
        Node nodeFound = findNode(name, current.leftChild);
        if ( nodeFound != null ) {
          // Only return from findNode if we have already found what we're looking for.
          return nodeFound;
        }
    }

    // Pre-order - go right
    if(current.rightChild != null)
    {
        System.out.println("going right to " + current.rightChild);
        return findNode(name, current.rightChild);
    }

    return null;
}

此外,在Java中,您不应该使用==来比较字符串。不会正常工作的。对于字符串,始终使用string.equals(...)。例如,请参阅上面的代码,以及这个SO问题。

 类似资料:
  • 我对如何在二叉查找树中排列节点的顺序有点困惑。左边的二叉查找树中的子树节点能比根节点大吗? 例如,以下内容会是二叉搜索树吗? 上面让我困惑的是1(3)的右子树是否可以大于原始根节点(2)。

  • 目前,我在理解如何在没有传递节点时从二进制搜索树中删除节点时遇到了一个问题。我有两个类,BSTSet和BSTNode,每个类都有一个remove方法。。 当我被传递一个节点时,我理解删除方法,但当我在根上调用remove方法并试图从node类中删除节点时,我不知道从何处开始。有人能告诉我吗?谢谢如果您想了解更多信息,请询问。

  • 在我们深入研究 ChannelHandler 内部之前,让我们花几分钟了解下这个 Netty 组件模型的基础。这里先对ChannelHandler 及其子类做个简单的介绍。 Channel 生命周期 Channel 有个简单但强大的状态模型,与 ChannelInboundHandler API 密切相关。下面表格是 Channel 的四个状态 Table 6.1 Channel lifeycle

  • 问题内容: 我正在编写一个使用二进制搜索树存储数据的程序。在以前的程序中(无关),我能够使用Java SE6随附的实现来实现链表。二进制搜索树是否有类似的东西,还是我需要“从头开始”? 问题答案: 您可以使用。被实现为一棵红黑树,这是一个自平衡二进制搜索树。

  • 我正在尝试从二叉查找树中删除节点。我可以成功地删除树上的任何其他节点,除了一个特殊的情况。如果目标节点有两个子节点,左边的子节点有右边的子树,我可以定位正确的替换节点,并将值切换到目标节点,但替换节点永远不会被删除。 看看上面的图片,如果我尝试删除17,程序将正确地导航到13,并用13替换17,但它不会像预期的那样删除原来的13。 我附加了我的remove方法和其中引用的方法。 这是我的Node类

  • 我可以运行这个程序,但由于某些原因,它会显示/放置随机字符,而不是二进制的初始值,而且我似乎无法将程序从十进制运行回二进制。我该如何改进这些代码。要明确说明它不会将二进制转换为十进制,我将如何将其转换回十进制转换为二进制,如果有一些代码可以帮助我,将不胜感激。