【问题标题】:How to make an efficient algorithm for chopping a binary search tree into two by given value?如何制定一种有效的算法,将二叉搜索树按给定值一分为二?
【发布时间】:2022-01-05 12:02:51
【问题描述】:

我实现了public BinarySearchTree<Node,T> chop(T x) 在元素x 处将我的树分成两部分。 SSet this 将包含元素 x,返回的 SSet 是一个包含元素 >= x 的 SSet。这应该适用于所有元素,无论它们是否在 this 中。

例如,假设s={2,4,6,8}。然后s.chop(3) 返回{4,6,8} 并且s 变为{2}。对于s.chop(4),我们会得到相同的结果。

实现了slowChop方法,但是它的时间复杂度是O(n),但是我需要在树平衡的时候把它降低到至少O(h)(其中h是高度树)。

public BinarySearchTree<Node,T> slowChop(T x) {
    Node sample = super.newNode();
    BinarySearchTree<Node,T> other = new 
    BinarySearchTree<Node, T>(sample);

    // Iterate through the n nodes in-order.
    // When see value >=x, add to new BST in O(height) time, and
    // remove it from this BST (on next iteration) in O(height) time.
        Iterator<T> it = iterator();
    T prev = null;
    while( it.hasNext() ) {
      T curr = (T)(it.next());
      if( c.compare(curr, x) >= 0 ) { // we have our first >= x 
other.add(curr);
        if( prev != null ) {
          this.remove(prev);          // safe to remove now
        }
        prev = curr;
      }
    }
    if( prev != null ) {
      this.remove(prev); // edge case, get that last one!
    }
    return other; 
}

 public BinarySearchTree<Node,T> chop(T x) {
        Node sample = super.newNode();
        BinarySearchTree<Node,T> other = new 
        BinarySearchTree<Node, T>(sample);
    // TODO: Implement this method. It should match slowChop in
    // behaviour, but should be faster :-)
    

    
    return other;
  }

【问题讨论】:

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


    【解决方案1】:

    确实,您的算法没有利用您从处理二叉搜索树这一事实中获得的效率。所以用中序遍历遍历树并不是要走的路。

    相反,执行二分搜索并切割连接两个节点的边,这些节点应该最终位于不同的树中。在切割时,您还需要将节点重新附加到执行先前切割的位置。复杂度与向树底部进行二分查找相同,因此为 O(logn)。

    这是一个假设您拥有常规 getter 和 setter 的实现:

    • Node 类:getLeftsetLeftgetRightsetRightgetValue
    • BinarySearchTree 类:getRoot,setRoot
    public BinarySearchTree<Node,T> chop(T x) {
        // Create two temporary dummy (sentinel) nodes to ease the process.
        Node rightRootParent = super.newNode();
        Node leftRootParent = super.newNode();
        
        // Set "cursors" at both sides
        Node rightParent = rightRootParent;
        Node leftParent = leftRootParent;
        
        // Start the binary search for x, cutting edges as we walk down
        Node node = this.getRoot();
        while (node != null) {
            // Decide for each node in the binary search path at which side it should go
            if (c.compare(node.getValue(), x) >= 0) {
                // Node should belong to the right-side tree
                rightParent.setLeft(node); // Establish edge
                rightParent = node; 
                node = node.getLeft(); // Move down
                rightParent.setLeft(null); // Cut next edge for now (it might get restored)
            } else { // Symmetric case
                leftParent.setRight(node);
                leftParent = node;
                node = node.getRight();
                leftParent.setRight(null);
            }
        }
        
        // Set the roots of both trees
        this.setRoot(leftRootParent.getRight());
        return BinarySearchTree<Node, T>(rightRootParent.getLeft());
    }
    

    【讨论】:

    • 但我的函数应该看起来像这样 public BinarySearchTree Chop(T x) { Node sample = super.newNode(); BinarySearchTree other = new BinarySearchTree(sample); // TODO: 实现这个方法。它应该在 // 行为中匹配 slowChop,但应该更快 :-) return other; }
    • 它说“实现这个方法”。这就是我所做的。我不明白问题是什么。
    • 是的,它是正确的,但我们被要求实现它并返回其他我已经添加了我们上面给出的功能如果你能帮我完成这部分,请帮助我完成
    • 抱歉,您试图编辑我的答案。我拒绝了。我不明白这个问题。这真的是关于命名变量,比如other吗?我使用了不同的变量名,因为sample 真的有example 代码的味道,否则这个名字是个糟糕的选择。
    • 抱歉,我在编辑我的错误时不小心编辑了你的!是的,我正在尝试遵循我们拥有的格式和变量,否则我们不会真正获得成绩,它显示为 0
    猜你喜欢
    • 2017-09-28
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多