【发布时间】:2016-01-08 00:40:52
【问题描述】:
在其中一个 C 练习中,我必须为给定深度的二叉树遍历创建一个函数。
我的第一个想法是使用 for 循环 (traverse_preorder_bad)。最后,我可以通过变量初始化 + if (traverse_preorder_working) 完成任务,但我仍然难以理解为什么 for 解决方案不起作用。
有人可以解释一下区别吗?有没有优雅的解决方案?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int RANGE = 1000;
typedef struct node_t
{
int data;
struct node_t *left;
struct node_t *right;
} node_t;
node_t *node_new(int data);
node_t *node_insert(node_t *tree, int data);
void traverse_preorder_working(node_t *tree, int depth);
void traverse_preorder_bad(node_t *tree, int depth);
int main(int argc, char *argv[])
{
node_t *tree = NULL;
// Random seed
srand((unsigned) time(NULL));
// Create the root node
tree = node_new(rand() % RANGE);
node_insert(tree, 5);
node_insert(tree, 1);
printf("Expected output:\n");
traverse_preorder_working(tree, 10);
printf("Bad output:\n");
traverse_preorder_bad(tree, 10);
return 0;
}
node_t *node_new(int data)
{
node_t *tree;
tree = malloc(sizeof(*tree));
tree->left = NULL;
tree->right = NULL;
tree->data = data;
return tree;
}
node_t *node_insert(node_t *tree, int data)
{
if (!tree)
return node_new(data);
if (data == tree->data)
return tree;
if (data < tree->data)
tree->left = node_insert(tree->left, data);
else
tree->right = node_insert(tree->right, data);
return tree;
}
void traverse_preorder_working(node_t *tree, int depth)
{
int i;
if (!tree)
return;
printf("%d\n", tree->data);
i = 1;
if (tree->left && i <= depth)
{
traverse_preorder_working(tree->left, depth - i);
i++;
}
i = 1;
if (tree->right && i <= depth)
{
traverse_preorder_working(tree->right, depth - i);
i++;
}
}
void traverse_preorder_bad(node_t *tree, int depth)
{
if (!tree)
return;
printf("%d\n", tree->data);
for (int i = 1; tree->left && i <= depth; i++)
traverse_preorder_bad(tree->left, depth - i);
for (int i = 1; tree->right && i <= depth; i++)
traverse_preorder_bad(tree->right, depth - i);
}
【问题讨论】:
-
优雅是什么意思?递归绝对优雅。递归的主要问题是调用激活帧的内存/时间要求,但除此之外,递归是完全优雅的。
-
@Jack,递归很棒!我只是不喜欢我的解决方案的样子。必须设置一个辅助变量两次,为了一件简单的事情要花很多行......
标签: c binary-search-tree