Retrieving a subset of a binary search tree recursively












1















For a binary tree object I'm implementing with the private fields



X key;
Y value;
Tree<X,Y> left;
Tree<X,Y> right;


I have a method public Tree<X,Y> subset(X startKey, X endKey) that needs to return a Tree including all of the keys in between the node with startKey and the node with endKey, and their corresponding values. This method also needs to be performed using recursion.



The problem I'm having is that I can't figure out a way to get a tree (which would probably look like a LinkedList) that ends with endKey, without including endKey.left and endKey.right. I figured I should start by calling the method recursively on either the left or right tree of the root depending on if the startKey is bigger or smaller than the root key, so:



if (this.key.compareTo(startKey) < 0) this.right.subset(startKey, endKey);
else if (this.key.compareTo(startKey > 0) this.right.subset(startKey, endKey);


That would keep navigating through the tree until it arrives on the node containing the key startKey. When I get to that point, I copy this to a new tree so I can avoid editing the original tree. This new tree has the node with startKey as its root, and then has the same children as the original.



This is where I'm stuck. The problems I know I'll have to deal with is navigating to endKey, making sure I stop there and don't include endKey.left or endKey.right, and return the subset correctly even as the method is "unwinding" from the recursive calls. I'm thinking that if I want to stop at endKey, I'll have to somehow keep a reference to its parent node, so that I can set the parent node's left or right child to the key/value pair in order to cut off the rest of endKey's children. However, since I don't really have node objects, and I can't add any methods or constructors, I don't know how I'd be able to maintain a reference to a parent tree. I also don't know how to attempt to pull this off while maintaining startKey as the root of the new tree.



In other words, I think I've managed to get a subset of a tree that starts on a lower level and continues to the bottom of the original tree. How can I recursively eliminate the children at the bottom I don't want and return my new subset?










share|improve this question


















  • 2





    If your subset can be a view, which means updates on it affect the original tree and vice versa, you can use the original tree as a backing tree in the subset. The method in the subset just check if you are "in range" of the subset, but you perform the methods on the original tree. And you can get a subset of the subset, which means it is recursive. This is exactly how TreeMap and its navigable sub views work.

    – Meini
    Nov 19 '18 at 13:16











  • Like Meini says, you could treat it like a view like List.sublist() does, or you could make a copy of the subtree. Which implementation is required for the homework. Also please post more code, maybe an MCVE.

    – xtratic
    Nov 19 '18 at 13:26













  • @xtratic I'm not sure I want to treat it as a view, wouldn't doing so mean I'm altering the original tree in the process of returning its subset? I'm pretty sure making a copy of the subtree is what I want.

    – user2709168
    Nov 19 '18 at 14:02











  • And in regards to what @Meini said, I think the subMap() method of TreeMap is exactly how I want, but I don't understand how to to "end" a submap, where I cut it off after it gains a child with a certain key.

    – user2709168
    Nov 19 '18 at 14:02
















1















For a binary tree object I'm implementing with the private fields



X key;
Y value;
Tree<X,Y> left;
Tree<X,Y> right;


I have a method public Tree<X,Y> subset(X startKey, X endKey) that needs to return a Tree including all of the keys in between the node with startKey and the node with endKey, and their corresponding values. This method also needs to be performed using recursion.



The problem I'm having is that I can't figure out a way to get a tree (which would probably look like a LinkedList) that ends with endKey, without including endKey.left and endKey.right. I figured I should start by calling the method recursively on either the left or right tree of the root depending on if the startKey is bigger or smaller than the root key, so:



if (this.key.compareTo(startKey) < 0) this.right.subset(startKey, endKey);
else if (this.key.compareTo(startKey > 0) this.right.subset(startKey, endKey);


That would keep navigating through the tree until it arrives on the node containing the key startKey. When I get to that point, I copy this to a new tree so I can avoid editing the original tree. This new tree has the node with startKey as its root, and then has the same children as the original.



This is where I'm stuck. The problems I know I'll have to deal with is navigating to endKey, making sure I stop there and don't include endKey.left or endKey.right, and return the subset correctly even as the method is "unwinding" from the recursive calls. I'm thinking that if I want to stop at endKey, I'll have to somehow keep a reference to its parent node, so that I can set the parent node's left or right child to the key/value pair in order to cut off the rest of endKey's children. However, since I don't really have node objects, and I can't add any methods or constructors, I don't know how I'd be able to maintain a reference to a parent tree. I also don't know how to attempt to pull this off while maintaining startKey as the root of the new tree.



In other words, I think I've managed to get a subset of a tree that starts on a lower level and continues to the bottom of the original tree. How can I recursively eliminate the children at the bottom I don't want and return my new subset?










share|improve this question


















  • 2





    If your subset can be a view, which means updates on it affect the original tree and vice versa, you can use the original tree as a backing tree in the subset. The method in the subset just check if you are "in range" of the subset, but you perform the methods on the original tree. And you can get a subset of the subset, which means it is recursive. This is exactly how TreeMap and its navigable sub views work.

    – Meini
    Nov 19 '18 at 13:16











  • Like Meini says, you could treat it like a view like List.sublist() does, or you could make a copy of the subtree. Which implementation is required for the homework. Also please post more code, maybe an MCVE.

    – xtratic
    Nov 19 '18 at 13:26













  • @xtratic I'm not sure I want to treat it as a view, wouldn't doing so mean I'm altering the original tree in the process of returning its subset? I'm pretty sure making a copy of the subtree is what I want.

    – user2709168
    Nov 19 '18 at 14:02











  • And in regards to what @Meini said, I think the subMap() method of TreeMap is exactly how I want, but I don't understand how to to "end" a submap, where I cut it off after it gains a child with a certain key.

    – user2709168
    Nov 19 '18 at 14:02














1












1








1








For a binary tree object I'm implementing with the private fields



X key;
Y value;
Tree<X,Y> left;
Tree<X,Y> right;


I have a method public Tree<X,Y> subset(X startKey, X endKey) that needs to return a Tree including all of the keys in between the node with startKey and the node with endKey, and their corresponding values. This method also needs to be performed using recursion.



The problem I'm having is that I can't figure out a way to get a tree (which would probably look like a LinkedList) that ends with endKey, without including endKey.left and endKey.right. I figured I should start by calling the method recursively on either the left or right tree of the root depending on if the startKey is bigger or smaller than the root key, so:



if (this.key.compareTo(startKey) < 0) this.right.subset(startKey, endKey);
else if (this.key.compareTo(startKey > 0) this.right.subset(startKey, endKey);


That would keep navigating through the tree until it arrives on the node containing the key startKey. When I get to that point, I copy this to a new tree so I can avoid editing the original tree. This new tree has the node with startKey as its root, and then has the same children as the original.



This is where I'm stuck. The problems I know I'll have to deal with is navigating to endKey, making sure I stop there and don't include endKey.left or endKey.right, and return the subset correctly even as the method is "unwinding" from the recursive calls. I'm thinking that if I want to stop at endKey, I'll have to somehow keep a reference to its parent node, so that I can set the parent node's left or right child to the key/value pair in order to cut off the rest of endKey's children. However, since I don't really have node objects, and I can't add any methods or constructors, I don't know how I'd be able to maintain a reference to a parent tree. I also don't know how to attempt to pull this off while maintaining startKey as the root of the new tree.



In other words, I think I've managed to get a subset of a tree that starts on a lower level and continues to the bottom of the original tree. How can I recursively eliminate the children at the bottom I don't want and return my new subset?










share|improve this question














For a binary tree object I'm implementing with the private fields



X key;
Y value;
Tree<X,Y> left;
Tree<X,Y> right;


I have a method public Tree<X,Y> subset(X startKey, X endKey) that needs to return a Tree including all of the keys in between the node with startKey and the node with endKey, and their corresponding values. This method also needs to be performed using recursion.



The problem I'm having is that I can't figure out a way to get a tree (which would probably look like a LinkedList) that ends with endKey, without including endKey.left and endKey.right. I figured I should start by calling the method recursively on either the left or right tree of the root depending on if the startKey is bigger or smaller than the root key, so:



if (this.key.compareTo(startKey) < 0) this.right.subset(startKey, endKey);
else if (this.key.compareTo(startKey > 0) this.right.subset(startKey, endKey);


That would keep navigating through the tree until it arrives on the node containing the key startKey. When I get to that point, I copy this to a new tree so I can avoid editing the original tree. This new tree has the node with startKey as its root, and then has the same children as the original.



This is where I'm stuck. The problems I know I'll have to deal with is navigating to endKey, making sure I stop there and don't include endKey.left or endKey.right, and return the subset correctly even as the method is "unwinding" from the recursive calls. I'm thinking that if I want to stop at endKey, I'll have to somehow keep a reference to its parent node, so that I can set the parent node's left or right child to the key/value pair in order to cut off the rest of endKey's children. However, since I don't really have node objects, and I can't add any methods or constructors, I don't know how I'd be able to maintain a reference to a parent tree. I also don't know how to attempt to pull this off while maintaining startKey as the root of the new tree.



In other words, I think I've managed to get a subset of a tree that starts on a lower level and continues to the bottom of the original tree. How can I recursively eliminate the children at the bottom I don't want and return my new subset?







java recursion tree binary-tree binary-search-tree






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 '18 at 13:02









user2709168user2709168

6812




6812








  • 2





    If your subset can be a view, which means updates on it affect the original tree and vice versa, you can use the original tree as a backing tree in the subset. The method in the subset just check if you are "in range" of the subset, but you perform the methods on the original tree. And you can get a subset of the subset, which means it is recursive. This is exactly how TreeMap and its navigable sub views work.

    – Meini
    Nov 19 '18 at 13:16











  • Like Meini says, you could treat it like a view like List.sublist() does, or you could make a copy of the subtree. Which implementation is required for the homework. Also please post more code, maybe an MCVE.

    – xtratic
    Nov 19 '18 at 13:26













  • @xtratic I'm not sure I want to treat it as a view, wouldn't doing so mean I'm altering the original tree in the process of returning its subset? I'm pretty sure making a copy of the subtree is what I want.

    – user2709168
    Nov 19 '18 at 14:02











  • And in regards to what @Meini said, I think the subMap() method of TreeMap is exactly how I want, but I don't understand how to to "end" a submap, where I cut it off after it gains a child with a certain key.

    – user2709168
    Nov 19 '18 at 14:02














  • 2





    If your subset can be a view, which means updates on it affect the original tree and vice versa, you can use the original tree as a backing tree in the subset. The method in the subset just check if you are "in range" of the subset, but you perform the methods on the original tree. And you can get a subset of the subset, which means it is recursive. This is exactly how TreeMap and its navigable sub views work.

    – Meini
    Nov 19 '18 at 13:16











  • Like Meini says, you could treat it like a view like List.sublist() does, or you could make a copy of the subtree. Which implementation is required for the homework. Also please post more code, maybe an MCVE.

    – xtratic
    Nov 19 '18 at 13:26













  • @xtratic I'm not sure I want to treat it as a view, wouldn't doing so mean I'm altering the original tree in the process of returning its subset? I'm pretty sure making a copy of the subtree is what I want.

    – user2709168
    Nov 19 '18 at 14:02











  • And in regards to what @Meini said, I think the subMap() method of TreeMap is exactly how I want, but I don't understand how to to "end" a submap, where I cut it off after it gains a child with a certain key.

    – user2709168
    Nov 19 '18 at 14:02








2




2





If your subset can be a view, which means updates on it affect the original tree and vice versa, you can use the original tree as a backing tree in the subset. The method in the subset just check if you are "in range" of the subset, but you perform the methods on the original tree. And you can get a subset of the subset, which means it is recursive. This is exactly how TreeMap and its navigable sub views work.

– Meini
Nov 19 '18 at 13:16





If your subset can be a view, which means updates on it affect the original tree and vice versa, you can use the original tree as a backing tree in the subset. The method in the subset just check if you are "in range" of the subset, but you perform the methods on the original tree. And you can get a subset of the subset, which means it is recursive. This is exactly how TreeMap and its navigable sub views work.

– Meini
Nov 19 '18 at 13:16













Like Meini says, you could treat it like a view like List.sublist() does, or you could make a copy of the subtree. Which implementation is required for the homework. Also please post more code, maybe an MCVE.

– xtratic
Nov 19 '18 at 13:26







Like Meini says, you could treat it like a view like List.sublist() does, or you could make a copy of the subtree. Which implementation is required for the homework. Also please post more code, maybe an MCVE.

– xtratic
Nov 19 '18 at 13:26















@xtratic I'm not sure I want to treat it as a view, wouldn't doing so mean I'm altering the original tree in the process of returning its subset? I'm pretty sure making a copy of the subtree is what I want.

– user2709168
Nov 19 '18 at 14:02





@xtratic I'm not sure I want to treat it as a view, wouldn't doing so mean I'm altering the original tree in the process of returning its subset? I'm pretty sure making a copy of the subtree is what I want.

– user2709168
Nov 19 '18 at 14:02













And in regards to what @Meini said, I think the subMap() method of TreeMap is exactly how I want, but I don't understand how to to "end" a submap, where I cut it off after it gains a child with a certain key.

– user2709168
Nov 19 '18 at 14:02





And in regards to what @Meini said, I think the subMap() method of TreeMap is exactly how I want, but I don't understand how to to "end" a submap, where I cut it off after it gains a child with a certain key.

– user2709168
Nov 19 '18 at 14:02












1 Answer
1






active

oldest

votes


















0














If you treat it as a view you don't actually cut it out, you just limit the methods to the range of the subset. When using iterator() e.g. the submap just has its own implementation of Iterator which start at the lower bound of the submap and just returns hasNext() == false when the upper bound is reached. The user won't notice that he is actually iterating over the original tree, because it's completly hidden. I hope this example gives you an idea about it.



public interface Tree<X, Y> extends Iterable<Tree<X, Y>> {
X getKey();
X getValue();
Tree<X, Y> floor(X key);
Tree<X, Y> ceiling(X key);
Tree<X, Y> subTree(X lo, X hi);
// ...
}

public class TreeImpl<X, Y> implements Tree<X, Y> {
final X key;
Y value;
TreeImpl<X, Y> left, right;

public TreeImpl(X key, Y value) {
this.key = key;
this.value = value;
}

@Override
public Iterator<Tree<X, Y>> iterator() {
return new TreeItr();
}

// Iterator starting at the most left to the most right;
private class TreeItr implements Iterator<Tree<X, Y>> {
// ...
}

@Override
public Tree<X, Y> subTree(X lo, X hi) {
return new SubTree<>(this, lo, hi);
}

private static class SubTree<X, Y> implements Tree<X, Y> {
final Tree<X, Y> backing;
final X lo, hi;

public SubTree(Tree<X, Y> backing, X lo, X hi) {
this.backing = backing;
this.lo = lo;
this.hi = hi;
}

@Override
public Iterator<Tree<X, Y>> iterator() {
return new SubTreeItr(backing.ceiling(lo), backing.floor(hi))
}

// Iterator starting at 'from' and returning 'hasNext() == false' after 'to'
// has returned
private class SubTreeItr implements Iterator<Tree<X, Y>> {
final Tree<X, Y> from, to;

public SubTreeItr(Tree<X, Y> from, Tree<X, Y> to) {
this.from = from;
this.to = to;
}

//...
}

@Override
public Tree<X, Y> subTree(X lo, X hi) {
// Check if lo > this.lo && hi < this.hi
return new SubTree<>(backing, lo, hi);
}
}
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53375269%2fretrieving-a-subset-of-a-binary-search-tree-recursively%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    If you treat it as a view you don't actually cut it out, you just limit the methods to the range of the subset. When using iterator() e.g. the submap just has its own implementation of Iterator which start at the lower bound of the submap and just returns hasNext() == false when the upper bound is reached. The user won't notice that he is actually iterating over the original tree, because it's completly hidden. I hope this example gives you an idea about it.



    public interface Tree<X, Y> extends Iterable<Tree<X, Y>> {
    X getKey();
    X getValue();
    Tree<X, Y> floor(X key);
    Tree<X, Y> ceiling(X key);
    Tree<X, Y> subTree(X lo, X hi);
    // ...
    }

    public class TreeImpl<X, Y> implements Tree<X, Y> {
    final X key;
    Y value;
    TreeImpl<X, Y> left, right;

    public TreeImpl(X key, Y value) {
    this.key = key;
    this.value = value;
    }

    @Override
    public Iterator<Tree<X, Y>> iterator() {
    return new TreeItr();
    }

    // Iterator starting at the most left to the most right;
    private class TreeItr implements Iterator<Tree<X, Y>> {
    // ...
    }

    @Override
    public Tree<X, Y> subTree(X lo, X hi) {
    return new SubTree<>(this, lo, hi);
    }

    private static class SubTree<X, Y> implements Tree<X, Y> {
    final Tree<X, Y> backing;
    final X lo, hi;

    public SubTree(Tree<X, Y> backing, X lo, X hi) {
    this.backing = backing;
    this.lo = lo;
    this.hi = hi;
    }

    @Override
    public Iterator<Tree<X, Y>> iterator() {
    return new SubTreeItr(backing.ceiling(lo), backing.floor(hi))
    }

    // Iterator starting at 'from' and returning 'hasNext() == false' after 'to'
    // has returned
    private class SubTreeItr implements Iterator<Tree<X, Y>> {
    final Tree<X, Y> from, to;

    public SubTreeItr(Tree<X, Y> from, Tree<X, Y> to) {
    this.from = from;
    this.to = to;
    }

    //...
    }

    @Override
    public Tree<X, Y> subTree(X lo, X hi) {
    // Check if lo > this.lo && hi < this.hi
    return new SubTree<>(backing, lo, hi);
    }
    }
    }





    share|improve this answer




























      0














      If you treat it as a view you don't actually cut it out, you just limit the methods to the range of the subset. When using iterator() e.g. the submap just has its own implementation of Iterator which start at the lower bound of the submap and just returns hasNext() == false when the upper bound is reached. The user won't notice that he is actually iterating over the original tree, because it's completly hidden. I hope this example gives you an idea about it.



      public interface Tree<X, Y> extends Iterable<Tree<X, Y>> {
      X getKey();
      X getValue();
      Tree<X, Y> floor(X key);
      Tree<X, Y> ceiling(X key);
      Tree<X, Y> subTree(X lo, X hi);
      // ...
      }

      public class TreeImpl<X, Y> implements Tree<X, Y> {
      final X key;
      Y value;
      TreeImpl<X, Y> left, right;

      public TreeImpl(X key, Y value) {
      this.key = key;
      this.value = value;
      }

      @Override
      public Iterator<Tree<X, Y>> iterator() {
      return new TreeItr();
      }

      // Iterator starting at the most left to the most right;
      private class TreeItr implements Iterator<Tree<X, Y>> {
      // ...
      }

      @Override
      public Tree<X, Y> subTree(X lo, X hi) {
      return new SubTree<>(this, lo, hi);
      }

      private static class SubTree<X, Y> implements Tree<X, Y> {
      final Tree<X, Y> backing;
      final X lo, hi;

      public SubTree(Tree<X, Y> backing, X lo, X hi) {
      this.backing = backing;
      this.lo = lo;
      this.hi = hi;
      }

      @Override
      public Iterator<Tree<X, Y>> iterator() {
      return new SubTreeItr(backing.ceiling(lo), backing.floor(hi))
      }

      // Iterator starting at 'from' and returning 'hasNext() == false' after 'to'
      // has returned
      private class SubTreeItr implements Iterator<Tree<X, Y>> {
      final Tree<X, Y> from, to;

      public SubTreeItr(Tree<X, Y> from, Tree<X, Y> to) {
      this.from = from;
      this.to = to;
      }

      //...
      }

      @Override
      public Tree<X, Y> subTree(X lo, X hi) {
      // Check if lo > this.lo && hi < this.hi
      return new SubTree<>(backing, lo, hi);
      }
      }
      }





      share|improve this answer


























        0












        0








        0







        If you treat it as a view you don't actually cut it out, you just limit the methods to the range of the subset. When using iterator() e.g. the submap just has its own implementation of Iterator which start at the lower bound of the submap and just returns hasNext() == false when the upper bound is reached. The user won't notice that he is actually iterating over the original tree, because it's completly hidden. I hope this example gives you an idea about it.



        public interface Tree<X, Y> extends Iterable<Tree<X, Y>> {
        X getKey();
        X getValue();
        Tree<X, Y> floor(X key);
        Tree<X, Y> ceiling(X key);
        Tree<X, Y> subTree(X lo, X hi);
        // ...
        }

        public class TreeImpl<X, Y> implements Tree<X, Y> {
        final X key;
        Y value;
        TreeImpl<X, Y> left, right;

        public TreeImpl(X key, Y value) {
        this.key = key;
        this.value = value;
        }

        @Override
        public Iterator<Tree<X, Y>> iterator() {
        return new TreeItr();
        }

        // Iterator starting at the most left to the most right;
        private class TreeItr implements Iterator<Tree<X, Y>> {
        // ...
        }

        @Override
        public Tree<X, Y> subTree(X lo, X hi) {
        return new SubTree<>(this, lo, hi);
        }

        private static class SubTree<X, Y> implements Tree<X, Y> {
        final Tree<X, Y> backing;
        final X lo, hi;

        public SubTree(Tree<X, Y> backing, X lo, X hi) {
        this.backing = backing;
        this.lo = lo;
        this.hi = hi;
        }

        @Override
        public Iterator<Tree<X, Y>> iterator() {
        return new SubTreeItr(backing.ceiling(lo), backing.floor(hi))
        }

        // Iterator starting at 'from' and returning 'hasNext() == false' after 'to'
        // has returned
        private class SubTreeItr implements Iterator<Tree<X, Y>> {
        final Tree<X, Y> from, to;

        public SubTreeItr(Tree<X, Y> from, Tree<X, Y> to) {
        this.from = from;
        this.to = to;
        }

        //...
        }

        @Override
        public Tree<X, Y> subTree(X lo, X hi) {
        // Check if lo > this.lo && hi < this.hi
        return new SubTree<>(backing, lo, hi);
        }
        }
        }





        share|improve this answer













        If you treat it as a view you don't actually cut it out, you just limit the methods to the range of the subset. When using iterator() e.g. the submap just has its own implementation of Iterator which start at the lower bound of the submap and just returns hasNext() == false when the upper bound is reached. The user won't notice that he is actually iterating over the original tree, because it's completly hidden. I hope this example gives you an idea about it.



        public interface Tree<X, Y> extends Iterable<Tree<X, Y>> {
        X getKey();
        X getValue();
        Tree<X, Y> floor(X key);
        Tree<X, Y> ceiling(X key);
        Tree<X, Y> subTree(X lo, X hi);
        // ...
        }

        public class TreeImpl<X, Y> implements Tree<X, Y> {
        final X key;
        Y value;
        TreeImpl<X, Y> left, right;

        public TreeImpl(X key, Y value) {
        this.key = key;
        this.value = value;
        }

        @Override
        public Iterator<Tree<X, Y>> iterator() {
        return new TreeItr();
        }

        // Iterator starting at the most left to the most right;
        private class TreeItr implements Iterator<Tree<X, Y>> {
        // ...
        }

        @Override
        public Tree<X, Y> subTree(X lo, X hi) {
        return new SubTree<>(this, lo, hi);
        }

        private static class SubTree<X, Y> implements Tree<X, Y> {
        final Tree<X, Y> backing;
        final X lo, hi;

        public SubTree(Tree<X, Y> backing, X lo, X hi) {
        this.backing = backing;
        this.lo = lo;
        this.hi = hi;
        }

        @Override
        public Iterator<Tree<X, Y>> iterator() {
        return new SubTreeItr(backing.ceiling(lo), backing.floor(hi))
        }

        // Iterator starting at 'from' and returning 'hasNext() == false' after 'to'
        // has returned
        private class SubTreeItr implements Iterator<Tree<X, Y>> {
        final Tree<X, Y> from, to;

        public SubTreeItr(Tree<X, Y> from, Tree<X, Y> to) {
        this.from = from;
        this.to = to;
        }

        //...
        }

        @Override
        public Tree<X, Y> subTree(X lo, X hi) {
        // Check if lo > this.lo && hi < this.hi
        return new SubTree<>(backing, lo, hi);
        }
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 6:00









        MeiniMeini

        41413




        41413






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53375269%2fretrieving-a-subset-of-a-binary-search-tree-recursively%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)