【问题标题】:Binary Tree Search for values less than二叉树搜索小于的值
【发布时间】:2014-03-06 02:37:46
【问题描述】:

我正在为大学工作创建一个二叉树算法,我需要开发一种算法来有效地找到所有小于指定值的值(它们需要按顺序排列)。

                     10
                    /  \
                   9    11
                  /       \
                 5         15
                / \        / \
               1   8      13  19
                         /  \
                        12  14   

这是我想出的解决方案(上图是你忘记二叉树的样子)。

private BinaryTreeNode root;
public int[] getBeforeJoinedNum(int num){
        usersInOrder = new ArrayList<User>();
        beforeNum(num, root);
        return usersInOrder;
}

private void beforeNum(int num, BinaryTreeNode n){
        if (n != null){
            beforeNum(num, n.getLeft());
            int nodeValue = n.getValue();
            if (num<nodeValue){
                usersInOrder.add(n.getValue());
                beforeNum(num, n.getRight());
            }
        }
    }

这个算法的问题在于它会进行不必要的比较。例如,如果我想要所有小于 10 的数字,代码将检查 9 剩下的所有数字(即 1、5、8)是否小于 10,而应该很明显任何小于 9 的数字当然应该是在列表中,无需任何比较。

如何让这个算法更高效?不幸的是,我不能使用 Java 集合框架,因为数据结构是课程的重点。

【问题讨论】:

  • BinaryTreeNodeUserNode 有何关系?
  • 只需创建一个获取任何给定父级的每个子级的方法。然后做一个比较。 if(num
  • root 似乎没有被初始化为任何东西,这意味着if(n != null) 永远不会是真的。
  • @NiklasB。对不起,我编辑了我的帖子
  • @alliteralmind 它是初始化的,我只是没有在我添加所有数据的地方添加长代码

标签: java algorithm binary-tree computer-science binary-search-tree


【解决方案1】:

对于您知道它们满足该属性的子树,只需执行标准的中序遍历:

private void addAll(UserNode n) {
    if (n == null) return;
    addAll(n.getLeft());
    usersInOrder.add(n.getValue());
    addAll(n.getRight());
}

private void beforeNum(int num, UserNode n){
    if (n == null) return;
    if (n.getValue() < num) {
        addAll(n.getLeft());
        usersInOrder.add(n.getValue());
        beforeNum(num, n.getRight());
    } else {
        beforeNum(num, n.getLeft());
    }
}

请注意,我还修复了beforeNum 中的一个逻辑错误:您将&lt;&gt; 混淆了,并且在正确的情况下您没有遍历正确的子树。

【讨论】:

    【解决方案2】:

    听说过中序搜索吗?下面是一个示例代码。修改它,使其接受“用户节点”的一个参数,并在仍然小于“用户节点”时停止遍历

    public void inOrderTraverse(Node root){
            if(root != null){
                inOrderTraverse(root.getLeft());
                System.out.print("  "+root.getData());
                inOrderTraverse(root.getRight());
            }
    
        }
    

    这是一个快速修改的版本:

    public void inOrderTraverse(Node root,UserNode n){
            if(root != null&&root.compareTo(n)<0){
                inOrderTraverse(root.getLeft());
                System.out.print("  "+root.getData());
                inOrderTraverse(root.getRight());
            }
    
        }
    

    无论如何你都需要遍历左边的所有节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      相关资源
      最近更新 更多