2015-04-07 5 views
1

Я пытаюсь написать метод, который вернет true, если бинарное дерево заполнено (каждый узел имеет 2 дочерних узла или нет) и false в противном случае. Это работает некоторое время, но не все. Любые предложения о том, где я ошибаюсь?Проверьте, заполнено ли бинарное дерево Java?

public static void testNum4() 
    { 
     System.out.println("How many nodes do you want in your tree?"); 
     int num=sc.nextInt(); 
     //TreeNode<Integer> root = TreeUtil.createBalancedNumberTree(num); Use to test for a balanced tree 
     TreeNode<Integer> root = TreeUtil.createIntegerTree(num); 
     TreeUtil.displayTreeInWindow(root); 
     System.out.println(isFull(root)); 
     TreeUtil.displayTreeInWindow (root); 
    } 

    public static boolean isFull(TreeNode<Integer> root) { 
    // pre: root of tree, 0 or more nodes 
    // post: returns true if the input tree is a full tree; false otherwise 

     if (root!=null) { 
      if ((root.getLeft() != null && root.getRight() != null) || (root.getRight() == null && root.getLeft() == null)) 
      { 
       return true; 
      } 
      else if (root.getLeft()!=null) 
      { 
       isFull(root.getLeft()); 
      } 
      else if (root.getRight()!=null) 
      { 
       isFull(root.getRight()); 
      } 
      else 
       return false; 

     } 
      return false; 
    } 
+0

Можете ли вы сказать, что ваша проблема четко? – user7

+0

Если дерево завершено, я всегда буду прав. Однако, если он неполный, иногда я становлюсь истинным (что неверно), а иногда и ложным. –

+1

Первое условие 'if' не является правильным. Если узел (корень) имеет 2 дочерних элемента, тогда вы возвращаете значение true, не проверяя их рекурсивно. – user7

ответ

3

Определения: бинарное дерево T называется полной, если каждый узел является либо листом или имеет ровно два дочерних узлов.

public static boolean isFull(TreeNode<Integer> root) 
// pre: root of tree, 0 or more nodes 
// post: returns true if the input tree is a full tree; false otherwise 
{ 

    if (root!=null) 
    { 
     if(root.getRight() == null && root.getLeft() == null) 
     { 
      return true; 
     } 
     if ((root.getRight() != null && root.getLeft() != null)) 
     { 
      return isFull(root.getLeft())&&isFull(root.getLeft()); 
     } 
    } 
    return false; 
} 
+0

Итак, где тест листьев? то есть как левое, так и правое являются нулевыми? – weston

+0

@weston Я только что редактировал. – lessmoon

+0

@ Начните свой ответ правильно, но если ПРАВЫЙ узел равен нулю, а LEFT - нет (может быть глубоким дочерним деревом), он будет работать медленно. – lessmoon

0

Вы не полностью пересекаете дерево. Используйте рекурсию, чтобы поразить все узлы. Проверьте корневой узел. Если детей нет, верните истину. Если есть дети, убедитесь, что их два, а затем проверьте каждый из них рекурсивно.

1

Попробуйте добавить возврат к каждому утверждению.

else if (root.getLeft()!=null && root.getRight()!=null) 
    { 
     return isFull(root.getLeft()) && isFull(root.getRight()); 
    } 

Кроме того, если корневой узел имеет значение NULL, то ваше дерево заполнено. Таким образом, последний возврат должен быть return true;

+1

Итак, если левая часть заполнена, даже не смотрите направо? – weston

+0

Справа я обновил свой андерсер. – JFPicard

1

Проблема else if и отсутствие return утверждений. Также нет необходимости проверять на null столько, и использование метода делает его более читаемым.

public static boolean isFull(TreeNode<Integer> node) { 

    if (node == null) return false; 

    if (isLeaf(node)) return true; 

    return isFull(node.getLeft()) && isFull(node.getRight()); 
} 

public static boolean isLeaf(TreeNode<Integer> node) { 
    return node.getRight() == null && node.getLeft() == null; 
} 
0

Я думаю, что если заявления должны быть следующими:

if (root.getRight() == null && root.getLeft() == null) 
{ 
    // The node has no children (full) 
    return true; 
} 
else if (root.getLeft() != null && root.getRight() != null) 
{ 
    // There are two children. Tree is only full if both sub trees are full 
    return isFull(root.getLeft()) && isFull(root.getRight()); 
} 
else 
{ 
    // Only one child 
    return false; 
} 
1

Все выше Алгоритмы возвращающие в этом случае (так как они не должны): complete binary tree . Итак, надеюсь, что это поможет:

//-1 means "false" 
public boolean full() { 
    int high = 0; 
    return (root != null && isFull(root, high) != -1); 
} 

public boolean isLeaf() { 
    return node.getRight() == null && node.getLeft() == null; 
} 

private int isFull(TreeNode<T> node, int high) 
{ 
    ++high; 
    if (node.isLeaf()) 
     return high; 
    else 
    { 
     int hLeft=0, hRight=0; 
     if(node.getLeft() != null) 
      hLeft = isFull(node.getLeft(), high); 
     if(node.getRight() != null) 
      hRight = isFull(node.getRight, high); 

     if ((hLeft == hRight) && (hLeft != -1)) 
      return ++high; 
     return -1; 
    } 
} 
+0

'Все алгоритмы [sic] выше возвращают true в этом случае' - что это? Учитывая, что вопрос объясняет, что «бинарное дерево заполнено (каждый узел имеет 2 дочерних узла или нет)» (похвальное усердие), он пытается ответить на другой вопрос. – greybeard

+0

Нажмите ссылку «полное двоичное дерево», чтобы вы могли видеть, в каком случае. Если вы проверите эти алгоритмы, они вернут true, они не должны этого делать, это не полное дерево, а полное дерево. – Adn

Смежные вопросы