Почему моя функция swapChildren () работает только частично? - PullRequest
0 голосов
/ 23 марта 2019

Я пытаюсь написать метод для двоичного дерева (не BST), который поменяет местами все левые и правые дочерние элементы.Мой класс, который является классом Binary Tree вместе с внутренним классом для Node:

import java.util.Scanner;

public class BinaryTree {

    private Node root;

    /**
     * Constructs an empty tree.
     */
    public BinaryTree() {
        root = null;
    }

    /**
     * Constructs a tree with one node and no children.
     * 
     * @param rootData the data for the root
     */
    public BinaryTree(Object rootData) {
        root = new Node();
        root.data = rootData;
        root.left = null;
        root.right = null;
    }

    /**
     * Constructs a binary tree.
     * 
     * @param rootData the data for the root
     * @param left     the left subtree
     * @param right    the right subtree
     */
    public BinaryTree(Object rootData, BinaryTree left, BinaryTree right) {
        root = new Node();
        root.data = rootData;
        root.left = left.root;
        root.right = right.root;
    }

    /**
     * Returns the height of the subtree whose root is the given node.
     * 
     * @param n a node or null
     * @return the height of the subtree, or 0 if n is null
     */
    private static int height(Node n) {
        if (n == null) {
            return 0;
        } else {
            return 1 + Math.max(height(n.left), height(n.right));
        }
    }

    /**
     * Returns the height of this tree.
     * 
     * @return the height
     */
    public int height() {
        return height(root);
    }

    /**
     * Checks whether this tree is empty.
     * 
     * @return true if this tree is empty
     */
    public boolean isEmpty() {
        return root == null;
    }

    /**
     * Gets the data at the root of this tree.
     * 
     * @return the root data
     */
    public Object data() {
        return root.data;
    }

    /**
     * Gets the left subtree of this tree.
     * 
     * @return the left child of the root
     */
    public BinaryTree left() {
        BinaryTree result = new BinaryTree();
        result.root = root.left;
        return result;
    }

    /**
     * Gets the right subtree of this tree.
     * 
     * @return the right child of the root
     */
    public BinaryTree right() {
        BinaryTree result = new BinaryTree();
        result.root = root.right;
        return result;
    }

    private static int countLeaves(Node n) {
        if (n == null) {
            return 0;
        }
        if (n.isLeaf()) {
            return 1;
        } else {
            return countLeaves(n.left) + countLeaves(n.right);
        }
    }

    public int countLeaves() {
        return countLeaves(root);
    }

    private static int countNodesWithOneChild(Node n) {
        if (n == null) {
            return 0;
        }
        if (n.hasOnlyOneChild()) {
            return 1 + countNodesWithOneChild(n.left) + countNodesWithOneChild(n.right);
        } else {
            return countNodesWithOneChild(n.left) + countNodesWithOneChild(n.right);
        }
    }

    public int countNodesWithOneChild() {
        return countNodesWithOneChild(root);
    }


    **public void swapChildren() {

        for(int i = 0; i < this.height()-1; i++) {
            root.swapChildren();
            root.right.swapChildren();
            root.left.swapChildren();
            Node toBeLeft = root.right;
            Node toBeRight = root.left;
            root.right = toBeRight;
            root.left = toBeLeft;
        }
        root.swapChildren();
    }**

    class Node {
        public Object data;
        public Node left;
        public Node right;

        public Node() {
            this.data = null;
        }

        public Node(Object data, Node left, Node right) {
            this.data = data;
            this.left = left;
            this.right = right;
        }

        public Node(Object data) {
            this.data = data;
            this.left = null;
            this.right = null;
        }

        public boolean isLeaf() {
            return (this.left == null && this.right == null);
        }

        public boolean hasOnlyOneChild() {
            if (this.left != null && this.right == null)
                return true;
            else if (this.left == null && this.right != null) {
                return true;
            }
            else {
                return false;
            }
        }

        public void swapChildren() {
            Node toBeRight = left;
            Node toBeLeft = right;
            left = toBeLeft;
            right = toBeRight;
        }

    }
}

Когда я запускаю свою тестовую программу, кажется, что большинство узлов переключилось.Однако не все из них имеют.Моя тестовая программа в методе main(Strings[] arg):

  BinaryTree questionTree = new BinaryTree("Is it a mammal?",
         new BinaryTree("Does it have stripes?",
            new BinaryTree("Is it a carnivore?",
               new BinaryTree("It is a tiger."),
               new BinaryTree("It is a zebra.")),
            new BinaryTree("It is a pig.")),
         new BinaryTree("Does it fly?",
            new BinaryTree("It is an eagle."),
            new BinaryTree("Does it swim?",
               new BinaryTree("It is a penguin."),
               new BinaryTree("It is an ostrich."))));

  boolean done = false;
  Scanner in = new Scanner(System.in);
  while (!done)
  {
     BinaryTree left = questionTree.left();
     BinaryTree right = questionTree.right();
     if (left.isEmpty() && right.isEmpty())
     {
        System.out.println(questionTree.data());
        done = true;
     }
     else
     {
        String response;
        do
        {
           System.out.print(questionTree.data() + " (Y/N) ");
           response = in.next().toUpperCase();
        } 
        while (!response.equals("Y") && !response.equals("N"));

        if (response.equals("Y"))
        {
           questionTree = left;         
        }
        else
        {
           questionTree = right;         
        }
     }
  }

1 Ответ

0 голосов
/ 23 марта 2019

Почему ваш внешний метод подкачки зацикливается?Почему бы вам не выполнить этот код один раз?Разве это не должно быть обработано с помощью обычной рекурсии, как и другие операции на дереве?И почему в этом методе вы оба вызываете root.swapChildren (), а затем меняете местами дочерние элементы root в этом методе?

Разве вы просто не хотите этого?:

public class BinaryTree {
    ...
    public void swapChildren() {
        root.swapChildren();
    }
    ....
    class Node {
        ...
        public void swapChildren() {
            if (right != null)
                right.swapChildren();
            if (left != null)
                left.swapChildren();
            Node toBeRight = left;
            Node toBeLeft = right;
            left = toBeLeft;
            right = toBeRight;
        }
        ...
    }
   ...
}
...