ANSI C, no recursive calls, write function to walk tree.
struct {
Node *next;
Node *child;
Node *parent;
int key} Node;
Не вижу решения, если хип не пользовать.
![HBZ :pain1:](./images/smilies/pain25.gif)
Any ideas?
A. Fig Lee wrote:Задали задачу:
ANSI C, no recursive calls, write function to walk tree.
struct {
Node *next;
Node *child;
Node *parent;
int key} Node;
Не вижу решения, если хип не пользовать.![]()
Any ideas?
Strannik223 wrote:A. Fig Lee wrote:Задали задачу:
ANSI C, no recursive calls, write function to walk tree.
struct {
Node *next;
Node *child;
Node *parent;
int key} Node;
Не вижу решения, если хип не пользовать.![]()
Any ideas?
Задача сводится к написанию стека. Если максимальная глубина дерава известна, то можно вместо стека использовать массив и int как указатель стека.
A. Fig Lee wrote:Ничего неизвестно. И что знацит - написание стека? Ето С, не С++.
Code: Select all
push(*myRoot);
while ((TreeNode tn = pop()) != null) {
foreach(TreeNode child = getChildList(tn))
push(child);
printf(tn->name);
}
Strannik223 wrote:A. Fig Lee wrote:Ничего неизвестно. И что знацит - написание стека? Ето С, не С++.
Эээ а что стек это понятие не из области структур данных, а из C++?
Ну значит прийдется тебе и reallocate вызывать когда надо будет.
Как известно (?) рекурсии заменяются алгоритмами с циклом и стеком. Что то вроде (pseudocode)Code: Select all
push(*myRoot);
while ((TreeNode tn = pop()) != null) {
foreach(TreeNode child = getChildList(tn))
push(child);
printf(tn->name);
}
push() & pop() - домашнее задание.
В push проверять не исчерпалась ли память стека и делать reallocate() если да. Без динамической памяти не обойтись, или по-тупому, зарезервировать массив побольше
olg2002 wrote:В данной задаче, если бы мы решали ее с помощью рекурсивной функции, у нас было бы два рекурсивных вызова в ее теле: один для child, другой для next. В этом основная трудность: кроме стека аргументов, нам нужен еще стек точек возврата. Очень хорошая задача на понимание рекурсии!
Code: Select all
struct {
Node *next;
Node *child;
Node *parent;
int key;
} Node;
bool walkTree( Node *top )
{
Node *current = top;
bool goUp = false;
while(current && (!goUp || current != top) )
{
if ( !goUp )
handleNode(current);
if (!goUp && current->child) {
current = current->child;
goUp = false;
} else if (current->next) {
current = current->next;
goUp = false;
} else {
current = current->parent;
goUp = true;
}
}
return (current == top);
}
SVK wrote:А при чем тут стек-нестек? Коли дана структура со ссылками - значит ее кто-то как-то построил в таком виде, и надо просто ее обойти, не пользуясь рекурсией и любыми не-ANSI прибамбасами. Разве не это требуется?
По-моему, так (если я чего-то не перепутал):Code: Select all
struct {
Node *next;
Node *child;
Node *parent;
int key;
} Node;
bool walkTree( Node *top )
{
Node *current = top;
bool goUp = false;
while(current && (!goUp || current != top) )
{
if ( !goUp )
handleNode(current);
if (!goUp && current->child) {
current = current->child;
goUp = false;
} else if (current->next) {
current = current->next;
goUp = false;
} else {
current = current->parent;
goUp = true;
}
}
return (current == top);
}
A. Fig Lee wrote:Специально три нарисовал, чтоб легче разбиратся.
После 1->2->3->4->5->4->8->10 обратно к ветке 3->7 Вы уже не вернетесь - нет операции обраной некст. А надо бы попапмуть до 3.
SVK wrote:А при чем тут стек-нестек? Коли дана структура со ссылками - значит ее кто-то как-то построил в таком виде, и надо просто ее обойти, не пользуясь рекурсией и любыми не-ANSI прибамбасами. Разве не это требуется?
По-моему, так (если я чего-то не перепутал):Code: Select all
struct {
Node *next;
Node *child;
Node *parent;
int key;
} Node;
bool walkTree( Node *top )
{
Node *current = top;
bool goUp = false;
while(current && (!goUp || current != top) )
{
if ( !goUp )
handleNode(current);
if (!goUp && current->child) {
current = current->child;
goUp = false;
} else if (current->next) {
current = current->next;
goUp = false;
} else {
current = current->parent;
goUp = true;
}
}
return (current == top);
}