(Java)按字母顺序排列的二叉树类没有按预期工作

时间:2018-04-27 06:55:54

标签: java data-structures tree binary-tree binary-search-tree

我需要为作业开发自己的二叉搜索树类。它应该对包含两个字符串,用户名和密码的数据类(User)进行排序,然后允许通过username变量对文本文件进行搜索。我成功地使用TreeSet测试了分配文件,发现如果使用整个搜索文件,搜索将返回大约300个正匹配。我根据我之前的工作认为我的二叉树类可以工作,但无论它从未通过搜索功能找到任何匹配,即使我知道这是不正确的。

有关此处未显示的代码的一些信息 -

  • 节点(称为BinTree)包含单个用户类以及左右节点,这是正常的。
  • getUserName是一个简单的访问者,它直接从节点的基础用户中检索userName。
  • 最初在手动创建的根节点上调用grow方法(b = new BinTree([此处输入文件阅读器中的第一个数据])
  • 由于这是一个处理用户名的程序,因此区分大小写非常重要。
  • 根据驱动程序类的编写方式,搜索方法只需要在找到具有正确userName的User时返回true,否则返回false。

这里是(新)grow()方法;

    public BinTree grow(BinTree root, BinTree newNode)  
  {
    if (root == null)
      return newNode;
    if (newNode.getUserName().compareTo(root.getUserName()) > 0)
    {
      if (root.right == null)
        root.right = newNode;
      else
        root.right.grow(root.right, newNode);
    }
    else
    {
      if (root.left == null)
        root.left = newNode;
      else
        root.left.grow(root.left, newNode);
    }
    return root;
  }

这里是(新)search()方法;

     public boolean search(BinTree r, String s) //search for a username, case sensitive
  {

    if (r.getUserName().compareTo(s) == 0)
      return true;
    else if (r.left != null && r.getUserName().compareTo(s) < 0)
      return r.left.search(r.left, s);
    else if (r.right != null)
      return r.right.search(r.right, s);

    return false;
  }

就像我说的那样,之前我做过一个更简单的二叉树(只有单个int值,而不是自定义数据类),我已经尝试过各种方法来编写这两种方法,但我觉得这样做&#39这是我不知道的难题中的一个关键部分。提前感谢您的帮助。

更新:感谢@Diasiare和@ c0der指出我的代码在返回和左/右方面存在错别字的明显问题。我接受了并改变了上面的代码来反映它。在运行时,该程序似乎仍然没有工作。然后我编写了这个show()方法来打印存储在树用户中的所有用户名。

public  void  show(BinTree    r)         
    {
    if (r != null)    
{ 
show(r.left);
System.out.println(r.getUserName());
show(r.right);
}   
    } // show

当我在更新并编译其他所有内容后调用它时,它实际上表明该列表是按字母顺序填充的用户名。这是输出的一小部分(有许多行)

ted@wisler.com
teddy@borglum.com
teddy@winkey.com
-->teodoro@harkin.com<--
teodoro@stranford.com
teodoro@talaska.com
teodoro@willette.com
tera@norise.com
tera@strevels.com
terence@lathrum.com
terence@morocco.com
terence@neidig.com
terence@rabago.com
teresa@chauvin.com
teresa@dockus.com

用箭头单挑的那个是我通过搜索.txt文件手动搜索并找到的文件。总而言之,通过这些新信息,我已经确定A)grow()正常工作,因为它按字母顺序从文件填充树,并且B)search()应该返回至少一个匹配。因此,我假设问题在于search()仍然存在。

UPDATE2:这是我为那些感兴趣的人调用search()的上下文。

try
      {
        BufferedReader fromPasswords = new BufferedReader(new FileReader("passwordInput.txt"));

        while ((line = fromPasswords.readLine()) != null)
        {
          System.out.println(line);
          if(b.search(b, line))
          {
            matches++;
          }
        }
        fromPasswords.close();
      }
      catch (Exception e)
      {
        System.out.println("Error while searching tree: " + e);
        System.exit(0);
      }

1 个答案:

答案 0 :(得分:0)

你的主要问题是搜索函数没有返回递归调用的结果,它应该读取如下内容:

public boolean search(BinTree r, String s) //search for a username, case sensitive
  {

    if (r.getUserName().compareTo(s) == 0)
      return true;
    else if (r.left != null && r.getUserName().compareTo(s) < 0)
      return r.left.search(r.left, s);
    else if (r.right != null)
      return r.right.search(r.right, s);

    return false;

  }

我还要注意这一点:

if (root == null)
  root = newNode;

没有多大意义。如果root为null,则最终会将newNode作为自己的子项插入。此外,您的方法无法通知树是空的。我建议您抛出NullPointerException,或者让方法返回新树。如果将来您希望它是一个平衡树,这将有所帮助,在这种情况下,根节点可能会发生变化。在这种情况下,解决方案将如下所示:

  public BinTree grow(BinTree root, BinTree newNode) 
  {
    if (root == null)
      return newNode;
    if (newNode.getUserName().compareTo(root.getUserName()) > 0)
    {
      if (root.right == null)
        root.right = newNode;
      else
        root.right.grow(root.right, newNode);
    }
    else
    {
      if (root.left == null)
        root.left = newNode;
      else
        root.left.grow(root.left, newNode);
    }
    return root;
  }

此外,正如c0der所说,行root.left.grow(root.right, newNode);应该是root.left.grow(root.left, newNode);