下面我写了一段代码来回答这个问题。请告诉我你好吗? 1)如果您在我的代码中发现任何缺陷 2)任何其他最佳解决方案?
问题: 关于树数据结构的问题,打印每个级别的总和(级别总和=兄弟姐妹数据的总和)?
struct tree{
int data;
struct *left;
struct *right;
};
API protype void EachLevelSum(struct tree * root);
我的回答是
void EachLevelSum(struct tree *root )
{
static int level=0;
static int a[100] = {0}; // I am assuming , at MAX 100 levels in tree
if( root == NULL )
{
return;
}
else
{
a[level += root->data;
level++;
EachLevelSum(root->left);
level--;
level++;
EachLevelSum(root->right);
level--;
if( level == 0 )
{
int i;
for( i=0; i<100 && a[i]!=0 ; i++)
{
printf("\n level: %d sum = %d", i, a[i] );
}
}
}
}
答案 0 :(得分:2)
我觉得这很不错!但是,我可以说一两件事,可以帮助你改进它。
1 - 使用静态变量。这不是禁止的,但你应该避免这种情况。现在,您如何看待您的解决方案本质上是递归的,并且您需要在调用之间共享数据?
一般方法是使用第二个函数,它包装递归调用,并将额外的参数传递给它。在你的情况下:
void eachLevelSum(struct tree*);
static void eachLevelSumRecursive(struct tree*, int level, int* results);
然后,像:
void eachLevelSum(struct tree* t) {
int results[100];
eachLevelSumRecursive(t, 0, results);
return;
}
然后在你的递归函数中,无论何时进入递归,你都可以将level参数作为level + 1传递,而不是像这样传递level ++和level-- = D:
eachLevelSumRecursive(t->left, level + 1, results);
eachLevelSumRecursive(t->right, level + 1, results);
请注意,这不仅有点清洁,还有其他优点。例如,这种方法可以在多线程环境中使用,而另一种方法则不能,因为它依赖于静态变量。
2 - 您可能希望使用typedef和更改结构的函数进一步封装树。如果您想了解更多相关信息,请随时提出。但是,对于你的练习来说,这根本不是必需的。
3 - 记住功能名称通常以小写字母开头。
这就是我要说的一切,你的代码非常干净!恭喜!
答案 1 :(得分:0)
我会避免使用level作为全局变量。在这种特殊情况下,没有那么重要,因为没有线程的复杂性或类似的东西。但是,养成避免使用全局变量的习惯是很好的。
总是首选使用局部变量而不是全局变量,除非必须使用全局变量并且需要小心。
我会在方法中添加level作为参数,而不是使用level ++和level--,我只需将level + 1传递给方法调用。
答案 2 :(得分:0)
您的代码似乎正确执行。在英语中,您的逻辑表明 -
对于您下降到树中的每个级别(左侧和右侧),跟踪您的深度并将data
添加到全局和跟踪变量a
。
除非你对你的结构做出重大改变 - 这是唯一的方法(我能想到)
答案 3 :(得分:0)
我认为你的代码很好。
作为替代方案,您可以使用BFS搜索:http://en.wikipedia.org/wiki/Breadth-first_search。这是样本C#代码
class Tree
{
public int data;
public Tree Left;
public Tree Right;
static int[] levels = new int[100];
static void EachLevelSum(Tree root)
{
// keeps track of each tree node's level
Dictionary<Tree, int> treeLevels = new Dictionary<Tree,int>();
treeLevels.Add(root, 0);
// Do a BFS search and update the level of each node
Queue<Tree> trees = new Queue<Tree>();
trees.Enqueue(root);
while (trees.Count != 0)
{
Tree node = trees.Dequeue();
int level = treeLevels[node];
if (node.Left != null)
{
treeLevels.Add(node.Left, level + 1);
trees.Enqueue(node.Left);
}
if (node.Right != null)
{
treeLevels.Add(node.Right, level + 1);
trees.Enqueue(node.Right);
}
}
foreach (Tree node in treeLevels.Keys)
{
int level = treeLevels[node];
levels[level] += node.data;
}
}
}