二叉树搜索小于的值

时间:2014-03-06 02:37:47

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

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

                     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集合框架,因为数据结构是课程的重点。

2 个答案:

答案 0 :(得分:2)

对于您知道他们履行财产的子树,只需执行标准的有序遍历:

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中的逻辑错误:您将<>混淆了,并且在正确的情况下您没有遍历正确的子树。

答案 1 :(得分:0)

有没有听过有关搜索?下面是一个示例代码。修改它,使它接受一个“用户节点”参数,当它仍然小于“usernode”时停止遍历

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());
        }

    }

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