通用BST不插入所有值并返回null

时间:2018-04-03 22:32:51

标签: java generics binary-search-tree

我试图实现通用二叉搜索树。我插入了7个整数并希望它们以inOrder遍历返回,但是它只返回4个不按顺序的值。然后我检查树是否包含特定值但它总是返回null并且我不确定为什么。我将发布下面的代码,任何关于为什么我的输出是什么的想法?我知道我的问题可能在我的插入和查找方法中,但不确定为什么,一些澄清会很好。感谢任何建议,谢谢!

插入整数15,10,20,5,13,​​11,19时的输出:

run:
InOrder: 
Inorder traversal:  10 15 11 19 
Is 11 in the tree? null
BUILD SUCCESSFUL (total time: 0 seconds)

Node.class:

class Node<E> {
  protected E element;
  protected Node<E> left;
  protected Node<E> right;

  public Node(E e) {
    element = e;
  }
}

BinarySearchTree.class:

class BinarySearchTree<E extends Comparable<E>> {
  private Node<E> root;

  public BinarySearchTree() {
    root = null;
  }

  public Node find(E e) {
    Node<E> current = root;

    while (e.compareTo(current.element) != 0) {
      if (e.compareTo(current.element) < 0) {
          current = current.left;
      }
      else {
          current = current.right;
      }
      if (current == null) {
          return null;
      }
    }
    return current;
  }

  public void insert(E e) {
    Node<E> newNode = new Node<>(e);

    if (root == null) {
        root = newNode;
    } else {
        Node<E> current = root;
        Node<E> parent = null;

        while (true) {
            parent = current;
            if (e.compareTo(current.element) < 0) {
                current = current.left;
            }
            if (current == null) {
                parent.left = newNode;
                return;
            } else {
                current = current.right;
                if (current == null) {
                    parent.right = newNode;
                    return;
                }
            }
        }
    }
  }

  public void traverse(int traverseType) {
    switch(traverseType) {
      case 1: System.out.print("\nPreorder traversal: ");
          preOrder(root);
          break;
      case 2: System.out.print("\nInorder traversal:  ");
          inOrder(root);
          break;
      case 3: System.out.print("\nPostorder traversal: ");
          postOrder(root);
          break;
    }
    System.out.println();
  }

  private void inOrder(Node<E> localRoot) {
    if (localRoot != null) {
      inOrder(localRoot.left);
      System.out.print(localRoot.element + " ");
      inOrder(localRoot.right);
    }
  }

  private void preOrder(Node<E> localRoot) {
    if (localRoot != null) {
      System.out.print(localRoot.element + " ");
      preOrder(localRoot.left);
      preOrder(localRoot.right);
    }
  }

  private void postOrder(Node<E> localRoot) {
    if (localRoot != null) {
      postOrder(localRoot.left);
      postOrder(localRoot.right);
      System.out.print(localRoot.element + " ");
    }
  }

}

主要课程:

public class BST_Test{
  public static void main(String[] args) {
    testInteger();
  }

  static void testInteger() {
    BinarySearchTree<Integer> itree = new BinarySearchTree<>();
    itree.insert(15);
    itree.insert(10);
    itree.insert(20);
    itree.insert(5);
    itree.insert(13);
    itree.insert(11);
    itree.insert(19);

    // Traverse tree
    System.out.print("InOrder: ");
    itree.traverse(2);

    // Search for an element
    System.out.println("Is 11 in the tree? " + itree.find(11));
  }
}

1 个答案:

答案 0 :(得分:1)

原因是您格式错误的代码隐藏了insert方法不正确的事实。

if语句没有左大括号{(以及随后的大括号},因为它编译),因此只有后续语句包含在这个if块:

if (e.compareTo(current.element) < 0)
    current = current.left

这意味着无论上述条件是否为真,都会执行以下操作...

if (current == null) {
    parent.left = newNode;
    return;
} ...

...如果是current != null,您的插入将继续向右移动:

... else {
    current = current.right;
    if (current == null) {
        parent.right = newNode;
        return;
    }
}

完整的当前错误的 代码,格式化/缩进时是:

public void insert(E e) {
    Node<E> newNode = new Node<>(e);

    if (root == null) {
        root = newNode;
    } else {
        Node<E> current = root;
        Node<E> parent = null;

        while (true) {
            parent = current;
            if (e.compareTo(current.element) < 0) // missing { ...
                current = current.left; // ... so only this is in the if block

            if (current == null) {
                parent.left = newNode;
                return;
            } else { // oops, this should be else to the e.compareTo(current.element) < 0 condition
                current = current.right;
                if (current == null) {
                    parent.right = newNode;
                    return;
                }
            }
        }
    }
}

已修复代码(假设允许重复):

public void insert(E e) {
    Node<E> newNode = new Node<>(e);

    if (root == null) {
        root = newNode;
    } else {
        Node<E> current = root;
        Node<E> parent = null;

        while (true) {
            parent = current;
            if (e.compareTo(current.element) < 0) {
                current = current.left;
                if (current == null) {
                    parent.left = newNode;
                    return;
                }
            } else {
                current = current.right;
                if (current == null) {
                    parent.right = newNode;
                    return;
                }
            }
        }
    }
}

故事的道德:保持代码格式良好并使用花括号来阻止你的麻烦。