Given the task to create your own implementation of a TreeSet , which should have the add(E e) and List<E> get() methods.

Does my code correctly illustrate the operation of a TreeSet ? If it is incorrect, then in what?

If it is at least partially correct, then how can I test that I created the tree, because my get method according to the condition of the problem returns a List ?

Implemented interface:

 public interface Tree<E> extends Iterable<E> { boolean add(E e); List<E> get(); int size(); } 

The implementation itself:

 public class SimpleTreeSet<E> implements Tree<E> { private Leaf<E> root; private List<E> list; private int size = 0; public SimpleTreeSet() { list = new LinkedList<>(); } @Override public boolean add(E e) { if (size == 0) { return initRootLeaf(e); } Leaf<E> newNode = new Leaf<>(e); Leaf<E> lastNode = findLastLeaf(root, newNode); if (lastNode == null) { return false; } // храню элементы для итератора и get list.add(newNode.element); if (lastNode.compareTo(newNode) > 0) { lastNode.right = newNode; size++; return true; } else { lastNode.left = newNode; size++; return true; } } // ищу последний лист дерева private Leaf<E> findLastLeaf( final Leaf<E> oldLeaf, final Leaf<E> newLeaf ) { Leaf<E> lastLeaf = oldLeaf; int compare = oldLeaf.compareTo(newLeaf); if (compare > 0 && oldLeaf.right != null) { lastLeaf = findLastLeaf(oldLeaf.right, newLeaf); return lastLeaf; } if (compare < 0 && oldLeaf.left != null) { lastLeaf = findLastLeaf(oldLeaf.left, newLeaf); return lastLeaf; } if (compare == 0) return null; return lastLeaf; } private boolean initRootLeaf(final E e) { root = new Leaf<>(e); list.add(e); size++; return true; } @Override public List<E> get() { return list; } @Override public int size() { return size; } @Override public Iterator<E> iterator() { return list.iterator(); } private class Leaf<E> implements Comparable<E> { private Leaf<E> right; private Leaf<E> left; private E element; private Leaf(E element) { this.element = element; } @Override public int compareTo(Object obj) { if (obj instanceof SimpleTreeSet.Leaf) { Leaf<E> node = (Leaf<E>) obj; return this.hashCode() - node.hashCode(); } throw new ClassCastException(); } @Override public int hashCode() { int hash = 31; hash = hash * 17 + element.hashCode(); return hash; } } } 
  • one
    Well, it would be logical for get to return a sorted list. And by the way, not the list itself, but its copy (!), Otherwise anyone can break the tree structure. After that, the list itself can be removed from the tree altogether (it is not needed). - pavel
  • one
    1. It would be great to see the Tree interface code in the question, because without it an example cannot be reproduced. 2. It is incorrect to store the List in this case, because the get method returns an unsorted list — the meaning in the entire tree disappears abruptly. The list is worth collecting from scratch right in get This at the same time protects against breakage of wood from the outside. 3. In if (lastNode.compareTo(newNode) > 0) - else string size++; and return true; there are in both branches - it means that they can be taken out for an if-else . - Regent
  • one
    4. Why in Leaf hashCode() method not to return just element.hashCode() ? Adding a constant ( 31 * 17 ) doesn't help anything. - Regent
  • one
    5. I see no point in checking if (obj instanceof SimpleTreeSet.Leaf) . First, otherwise ClassCastException is still thrown, and second, it is a private class, so you can be more or less sure that obj is Leaf<E> . Yes that there: it is possible to refuse in general implements Comparable<E> and to make the compareTo(Leaf<E> leaf) method compareTo(Leaf<E> leaf) . This is perhaps a controversial statement, but why make the small auxiliary inner class "universal"? - Regent
  • one
    2. Yes, it will be necessary "to pass somehow slyly". I think the creation of a tree and its detour is the purpose for which the task was intended. 4. And these "all" somehow argue their opinion, and did they really mean a simple increase of 527 ? - Regent

0