计算树中的所有节点

Counting all nodes in a tree

本文关键字:节点 计算      更新时间:2023-10-16

这是我当前的代码。它工作正常,但是我想不出将根节点添加到计数中的方法,因为由于程序是递归的,它总是被添加很多次。

int countTree(tnode<T> *t)
{
int count = 0;

if (t != NULL)
{
count = count + countTree(t->left);
if (t->left)
{ count++; }
count = count + countTree(t->right);
if (t->right)
{ count++; }
}

return count;
};

二叉树中节点计数的通常递归是1 + count(left sub-tree) + count(right sub-tree),其中count(null)返回 0。

所以它会像这样:

int count(node *root)
{
if (!root) { return 0; }
return 1 + count(root->left) + count(root->right);
}

只需有一个函数,该函数环绕 countTree,如果第一个节点不为 null,则加 1。

例如

int BaseCountFunc(tnode<T> *t)
{
int returnValue;
returnValue = 0;
if (t!=nullptr)
{
returnValue = 1 + countTree(t->left) + countRight(t->right);
}
return returnValue;
}

或者如何在每个节点上仅调用一次方法时迭代

这取决于您的树实现,这是一个基于boost::intrusive数据结构和算法的示例树(修复程序尚未在boost中发布)。要点是:

  • header节点(根)不是树的一部分,它的左节点指向第一个节点,最后一个节点指向最后一个项目,标头节点本身是结束迭代器节点
  • 下一个节点由next()返回,它按顺序返回下一个节点 - 当它到达底部(示例中为 3)时,它会返回到顶部,然后找到下一个minimum()节点(在本例中为 5)。

示例代码

#include <iostream>
struct node {
int value;
node * left;
node * right;
node * parent;
node( int v )
: value( v )
, left( nullptr )
, right( nullptr )
, parent( nullptr )
{}
node() : node( 0 ) {}
~node() {}
};

要打印节点:

std::ostream & operator<<( std::ostream & os, const node * n ) {
return os << ( n ? n->value : 0 );
}

要迭代:

node * minimum( node * n ) {
for ( node * l = n->left; l; l = n->left ) n = l;
return n;
}
node * maximum( node * n ) {
for ( node * r = n->right; r; r = n->right) n = r;
return n;
}
node * next( node * n ) {
if ( ! n ) return nullptr;
if ( n->right ) return minimum( n->right );
node * p = n;
node * x = p->parent;
while ( p == x->right ) {
p = x;
x = x->parent;
}
return p->right != x ? x : p;
}
node * prev( node * n ) {
if ( ! n ) return nullptr;
if ( n->left ) return maximum( n->left );
node * p = n;
node * x = p->parent;
while ( p == x->left ) {
p = x;
x = x->parent;
}
return p->left != x ? x : p;
}

简单迭代器使用next()来确定接下来要访问的内容:

void iterate( node * root, void(*func)( node * n ) ) {
node * n = root->left;
node * e = root;
while ( n != e and n ) {
func( n );
n = next( n );
}
}

使用它来计算:

static void counter( node * n ) {
static uint count( 0 );
++count;
std::cout << count << " node [" << n  << "]" << std::endl;
}

树看起来像这样:

/*
* a binary tree
* for each node, left nodes are smaller, right nodes are bigger
*
* header node is just a header node, not part of a tree
* header.left points to the "first node" in example below to 3
* header.right points to the "last node" in the example below 2
* end iterator is the header itself
* header node is not part of a tree
*
--------  R ------
|         |      |
|         4      |
|       /       |
|     2      5 < +
|    /  
+> 1     3
*/

手动创建树 - 无论如何,您都会使用boost::intrusive而不是此代码......

void test() {
node r( 999 );
node n1( 1 );
node n2( 2 );
node n3( 3 );
node n4( 4 );
node n5( 5 );
// setup n2
n2.left = & n1;
n2.right = & n3;
n1.parent = & n2;
n3.parent = & n2;
// setup n4
n4.left = & n2;
n2.parent = & n4;
n4.right = & n5;
n5.parent = & n4;
n4.parent = & r;
// setup header node - header not part of a tree
r.left = & n1;
r.right = & n5;
iterate( & r, & counter );
}

int main() {
test();
}

结果:

1 node [1]
2 node [2]
3 node [3]
4 node [4]
5 node [5]

每个节点都已考虑,不包括标头节点。 不确定这是否有帮助。

试试这个...

int countTree(tnode<T> *t)
{  
if (t==NULL)
return 0;
return 1+countTree(t->left)+countTree(t-right);
}