为什么我的swapChildren()函数只能部分起作用?

时间:2019-03-23 03:38:43

标签: java binary-tree

我正在尝试为二叉树(不是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 :(得分:0)

为什么您的外部交换方法循环?您为什么不只执行一次该代码?难道不应该像树上的其他操作一样通过普通递归来处理它吗?为什么在该方法中,您既调用root.swapChildren(),又在该方法中交换根的子级?

您不只是想要这个吗?:

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;
        }
        ...
    }
   ...
}