Бинарные деревья, чтобы найти партнера по танцу - PullRequest
0 голосов
/ 24 ноября 2018

Я написал код, но тесты падают.Я не могу найти, что я делаю неправильно.Например:

FAILURE: testRunOutOfPartnersThenFindSomeMore 2 мсек, вес: 0 единиц Описание: Этот тест проверяет, может ли ваше дерево опустеть, а затем снова заполниться.Тип исключения: класс java.lang.NullPointerException

FAILURE: testFemaleTreeImplementation 5 мсек, вес: 0 единиц Описание: Этот тест проверяет, правильно ли работает ваше дерево.Тип исключения: класс java.lang.AssertionError Подробная информация: Ваша реализация нашла пару, когда она не должна иметь.

Dancer.java

   public interface Dancer {

        public enum Gender {
            MALE, FEMALE
        }

        public int getID();
        public Gender getGender();
        public int getHeight();

    }

Dancers.java

import java.util.AbstractMap.SimpleEntry;
import java.util.List;

public interface Dancers {
    public SimpleEntry<Dancer, Dancer> findPartnerFor(Dancer d) throws IllegalArgumentException;

    /*
     * Returns waiting list as a list (both men and women)
     * Ordered shortest --> longest
     * If man and woman are having the same height,
     * then ordering should be woman, man
     */
    public List<Dancer> returnWaitingList();
}

HW01.java

import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;

public class HW01 implements Dancers {
    public SearchTree maleTree;
    public SearchTree femaleTree;

    public void createTree(SearchTreeNode n) {
        if (n.getKey().getGender().equals(Dancer.Gender.MALE)) {
            this.maleTree = new SearchTree(n);
        } else {
            this.femaleTree = new SearchTree(n);
        }
    }

    @Override
    public SimpleEntry<Dancer, Dancer> findPartnerFor(Dancer candidate) throws IllegalArgumentException {
        if (candidate == null) throw new IllegalArgumentException();
        if (candidate.getGender().equals(Dancer.Gender.MALE)) {
            if (this.femaleTree != null) {
                // If no match, add to opposite tree
                SearchTreeNode match = this.femaleTree.match(candidate);
                if (match != null) {
                    // Remove node from tree
                    this.femaleTree.delete(match);
                    return new SimpleEntry<>( candidate, match.getKey() );
                } else {
                    if (this.maleTree != null) {
                        this.maleTree.getRoot().insert(new SearchTreeNode(candidate));
                    } else {
                        this.createTree(new SearchTreeNode(candidate));
                    }
                }
            } else {
                if (this.maleTree != null) {
                    this.maleTree.getRoot().insert(new SearchTreeNode(candidate));
                } else {
                    this.createTree(new SearchTreeNode(candidate));
                }
            }
        } else {
            if (this.maleTree != null) {
                // If no match, add to opposite tree
                SearchTreeNode match = this.maleTree.match(candidate);
                if (match != null) {
                    this.maleTree.delete(match);
                    return new SimpleEntry<>( candidate, match.getKey() );
                } else {
                    if (this.femaleTree != null) {
                        this.femaleTree.getRoot().insert(new SearchTreeNode(candidate));
                    } else {
                        this.createTree(new SearchTreeNode(candidate));
                    }
                }
            } else {
                if (this.femaleTree != null) {
                    this.femaleTree.getRoot().insert(new SearchTreeNode(candidate));
                } else {
                    this.createTree(new SearchTreeNode(candidate));
                }
            }
        }
        return null;
    }

    @Override
    public List<Dancer> returnWaitingList() {
        List<Dancer> resultList = new ArrayList<>();
        if (femaleTree != null) resultList.addAll(femaleTree.getMembers());
        if (maleTree != null) resultList.addAll(maleTree.getMembers());

        return resultList;
    }

SearchTree.java

import java.util.ArrayList;
import java.util.List;

class SearchTree {
    private SearchTreeNode root;
    private List<Dancer> members = new ArrayList<>();

    SearchTree(SearchTreeNode node) {
        this.root = node;
    }

    SearchTreeNode getRoot() {
        return root;
    }

    SearchTreeNode match(Dancer d) {
        return this.root.match(new SearchTreeNode(d));
    }

    void delete(SearchTreeNode tn) {
        root = delete(root, tn);
    }

    private SearchTreeNode delete(SearchTreeNode n, SearchTreeNode tn) {
        if (n == null) {
            return null;
        }

        if (n == tn) {
            // n is the node to be removed
            if (n.getLeft() == null && n.getRight() == null) {
                return null;
            }
            if (n.getLeft() == null) {
                return n.getRight();
            }
            if (n.getRight() == null) {
                return n.getLeft();
            }

            // if we get here, then n has 2 children
            SearchTreeNode smallest = getLastOnTheLeft(n.getRight());
            n.setKey(smallest.getKey());
            n.setRight(delete(n.getRight(), smallest));
            return n;
        }

        else if (tn.getKey().getHeight() < n.getKey().getHeight()) {
            n.setLeft( delete(n.getLeft(), tn) );
            return n;
        }

        else {
            n.setRight( delete(n.getRight(), tn) );
            return n;
        }
    }

    private SearchTreeNode getLastOnTheLeft(SearchTreeNode start) {
        SearchTreeNode candidate = null;
        SearchTreeNode parent = null;
        SearchTreeNode node = start;

        while (node != null) {
            if ( node.getLeft() != null ) {
                parent = node;
                candidate = node.getLeft();
            }

            node = node.getLeft();
        }

        if (parent != null) {
            parent.setLeft(null);
        }

        return candidate;
    }

    List<Dancer> getMembers() {
        members = new ArrayList<>();
        preOrderTraversal(root);
        return members;
    }

    private void preOrderTraversal(SearchTreeNode root){
        if (root == null) {
            return;
        }
        members.add(root.getKey());
        preOrderTraversal(root.getLeft());
        preOrderTraversal(root.getRight());
    }
}

SearchTreeNode.java

public class SearchTreeNode {
    private Dancer key;
    private SearchTreeNode left;
    private SearchTreeNode right;

    SearchTreeNode(Dancer key) {
        this.key = key;
        this.left = null;
        this.right = null;
    }

    void setKey(Dancer key) {
        this.key = key;
    }

    Dancer getKey() {
        return key;
    }

    void setLeft(SearchTreeNode left) {
        this.left = left;
    }

    SearchTreeNode getLeft() {
        return left;
    }

    void setRight(SearchTreeNode right) {
        this.right = right;
    }

    SearchTreeNode getRight() {
        return right;
    }

    void insert(SearchTreeNode node) {
        if (node.key.getHeight() < this.key.getHeight()) {
            if (left != null) {
                left.insert(node);
            } else {
                this.setLeft(node);
            }
        } else {
            if (right != null) {
                this.getRight().insert(node);
            } else {
                this.setRight(node);
            }
        }
    }

    SearchTreeNode match(SearchTreeNode node) {
        if (node.getKey().getGender().equals(Dancer.Gender.MALE)) {
            if (key.getHeight() < node.getKey().getHeight()) {
                if (right != null) {
                    return right.match(node);
                } else {
                    return this;
                }
            } else {
                if (left != null) {
                    return left.match(node);
                } else {
                    return null;
                }
            }
        } if (node.getKey().getGender().equals(Dancer.Gender.FEMALE)) {
            if (key.getHeight() > node.getKey().getHeight()) {
                if (left != null) {
                    return left.match(node);
                } else {
                    return this;
                }
            } else {
                if (right != null) {
                    return right.match(node);
                } else {
                    return null;
                }
            }
        }

        return node;
    }

    @Override
    public String toString() {
        return "SearchTreeNode {" +
                "key = " + key +
                '}';
    }
}
...