подсчета числа вершин в бинарном дереве

Я хочу подсчитать нет листовых узлов: Примечание: не удается использовать переменную уровня global/class Я implmeted следующим Алго, и она отлично работает.Но я хочу, чтобы подпись метода была

countLeaves(Node node)

Я знаю, что могу перегрузить methds и вызвать метод 2 args sig из 1 args, но не хочу этого делать.Кто-нибудь может предложить другой способ?

int countLeaves(Node node,int count){
        if(node==null)
            return 0;

        if(node.left==null && node.right==null){
            return 1+count;
        }else{
            int lc = countLeaves(node.left, count);
            int total = countLeaves(node.right, lc);
            return total;
        }
    }

7 ответов


int countLeaves(Node node){
  if( node == null )
    return 0;
  if( node.left == null && node.right == null ) {
    return 1;
  } else {
    return countLeaves(node.left) + countLeaves(node.right);
  }
}

Вы делаете то же самое, что и раньше, но вместо того, чтобы удерживать текущий счет, когда мы идем, мы просто говорим, что возвращаем результат суммы левого и правого узла. Они, в свою очередь, рекурсивно вниз, пока они не попали в basecases.


вам не нужно проходить count вниз по стеку вызовов, только из:

int countLeaves(Node node)
{
    if(node==null) {
        return 0;
    }
    if(node.left==null && node.right==null) {
        return 1;
    }
    return countLeaves(node.left) + countLeaves(node.right);
}

мы можем применить два подхода , один рекурсивный и итерационный(реализация на основе очереди ) .Здесь я собираюсь объяснить оба метода.

Рекурсивное Решение

int count_leaf(Node node)
{
 if(node==NULL)
  return 0;
  if(node->left==NULL && node->right==NULL)
  return 1;
   return count_leaf(node->left)+count_leaf(node->right);
}

Второй метод является итеративным (реализация на основе очереди), идея берется из обхода порядка уровня дерева.

int count_leaf(Node root)
{
int count=0;
  if(root==NULL)
    return 0;

  queue<Node *> myqueue;
  myqueue.push(root);

  while(!myqueue.empty())
{
  Node temp;
   temp=myqueue.top();   //Take the front element of queue 
   myqueue.pop();        //remove the front element of queue
  if(temp->left==NULL && temp->right==NULL)
   count++;
   if(temp->left)
    myqueue.push(temp->left);
   if(temp->right)
   myqueue.push(temp->right);
}
return count;
}

Я надеюсь, что эти решения помогут вам.


заполнить ??? часть себя.

int countLeaves(Node node){
    if (node==null)
        return 0;

    if (node.left==null && node.right==null){
        return 1;
    } else {
        int lc = countLeaves(node.left);
        int rc = countLeaves(node.right);
        return ???;
    }
}

поскольку я все еще тестирую эту реализацию, никаких обещаний безошибочной работы не сделано. Если есть конкретные проблемы с реализацией, я рад получить обратную связь.

Первоначально я получаю благоприятные результаты:

#region CountNode utility
private int CountNode(Node node, Direction d) {
    Func<Direction, Node> leaf = (dir) => {
        return dir == Direction.Left ? node.Left : node.Right;
    };

    var done = leaf(d) == null;
    var root = node;
    var stack = new Stack<Node>( );
    var count = 0;

    while(!done) {
        if (node != null) {
            stack.Push(node);
            node = leaf(d);
        }
        else {
            if(stack.Count > 0) {
                node = stack.Pop( );
                //  back to root, time to quit
                if(node == root) {
                    done = true;
                    continue;
                }

                //  count nodes when popped
                ++count;

                //  flip direction
                var flip = d == Direction.Left ? Direction.Right : Direction.Left;
                //  get the leaf node
                node = leaf(flip);
            }
            else {
                done = true;
            }
        }
    }

    return count;
}
#endregion

использование:

var actLeftCount = CountNode(root, Direction.Left);
var actRightCount = CountNode(root, Direction.Right);

это имеет особое преимущество, давая подсчет только узлов на Left. Я могу передать любой узел в метод и получить статистику для тот же.


то же, что и в первом комментарии.

 int getLeafNodeCount(Node<T> node) {
        if(node == null) {
             return 0;
        } 
        if (node.leftChild == null && node.rightChild == null) {
             return 1;
        } else {
             return getLeafNodeCount(node.leftChild) + getLeafNodeCount(node.rightChild);
        }
   }

public int getLeafsCount(BSTNode<T> node, int count) {
    if(node == null || node.getData() == null){
        return count;
    }
    else if(isLeaf(node)){
        return ++count;
    }else{  
        int leafsLeft =  getLeafsCount((BSTNode<T>) node.getLeft(), count);
        int leafsCount = getLeafsCount((BSTNode<T>) node.getRight(), leafsLeft);

        return leafsCount;
    }

}