【问题标题】:How do I modify my tree traversal program that I wrote in C so that it doesn't rely on recursion?如何修改我用 C 编写的树遍历程序,使其不依赖递归?
【发布时间】:2019-09-23 00:24:54
【问题描述】:

我有一个用 C 语言编写的程序,它以反向前序、反向中序和反向后序遍历树,其各个函数严重依赖递归。我将如何修改这些函数以使它们执行完全相同的任务但不使用任何递归?我花了很多时间试图通过使用临时存储值的变量来解决这个问题,但不幸的是我一直在画一个空白。我在 Ubuntu Linux BTW 上使用 GCC 编译器。

这是我的代码:

#include <stdio.h> 
#include <stdlib.h> 


struct node 
{ 
    int data; 
    struct node* left; 
    struct node* right; 
}; 


struct node* newNode(int data) 
{ 
    struct node* node = (struct node*) 
                                malloc(sizeof(struct node)); 
    node->data = data; 
    node->left = NULL; 
    node->right = NULL; 

    return(node); 
} 


void reversePostOrder(struct node* node) 
{ 
    if (node == NULL) 
        return; 


    reversePostOrder(node->right);


    reversePostOrder(node->left); 



    printf("%d ", node->data); 
} 


void reverseInOrder(struct node* node) 
{ 
    if (node == NULL) 
        return;  


    reverseInOrder(node->right);


    printf("%d ", node->data); 


    reverseInOrder(node->left);


} 


void reversePreOrder(struct node* node) 
{ 
    if (node == NULL) 
        return; 


    printf("%d ", node->data); 


    reversePreOrder(node->right);


    reversePreOrder(node->left); 


}    


int main() 
{ 


    struct node *root = newNode(1);
    root->left           = newNode(-2);
    root->right      = newNode(-3);
    root->left->left     = newNode(4);
    root->left->right = newNode(5);
    root->right->left =newNode(6);
    root->right->right=newNode(7);
    root->left->right->left=newNode(-8);
    root->left->right->right=newNode(-9);
    root->right->right->left=newNode(10);
    root->right->right->right=newNode(11);
    root->right->right->right->left=newNode(-12);
    root->right->right->right->right=newNode(-13);
    root->right->right->right->right->left=newNode(14);
    printf("\nReverse Preorder traversal of binary tree is \n"); 
    reversePreOrder(root); 

    printf("\nReverse Inorder traversal of binary tree is \n"); 
    reverseInOrder(root); 

    printf("\nReverse Postorder traversal of binary tree is \n"); 
    reversePostOrder(root); 

    getchar(); 
    return 0; 
} 

【问题讨论】:

  • 想想每次递归时每个node 变量是如何存储在堆栈中的,以及当你返回时该变量是如何从堆栈中删除的。您需要一个节点数组,其大小为您希望允许的最大深度、一个深度计数器和一些关于最后一次移动是在该级别是左还是右的内存。

标签: c recursion tree


【解决方案1】:

问题变得困难,因为您的列表节点没有指向其父节点的指针。当一个迭代/命令式过程沿着当前节点的左或右链接前进以导航到另一个节点时,它没有反向路径。

解决这个问题有两种一般的方法:

  1. 维护一个显式堆栈,使过程能够导航到父级。

  2. 临时改变树本身以提供返回路径。也就是说,暂时用指向父级的反向指针覆盖leftright链接;然后在返回树时恢复值。

如果树是保证最大深度的平衡树,那么 (1) 可以用一个相当小的、固定大小的数组来实现。

【讨论】:

    【解决方案2】:

    您可以使用堆栈来存储父节点和数组(如果之前处理过或未处理过节点)。顺序示例

    push(root)
    while stack is not empty()
       parent=stack.top()
       if parent->left and done[parent->left]==false
           left=parent->left
           push(parent)
           done[left]=true
           continue
       if done[parent]==false
           process(parent)
           done[parent]=true
       if parent->right and done[parent->right]==false
           right=parent->right
           push(right)
           done[right]=true
           continue
       stack.pop()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多