【问题标题】:BST nodes are not saving when trying to create a preorder traversal of a previous tree in c尝试在 c 中创建前一棵树的前序遍历时,BST 节点未保存
【发布时间】:2017-04-03 01:40:31
【问题描述】:

我试图查看树 A 是否是树 B 的前序遍历,为此,我创建了两棵树,它们在遍历期间应该保存值。但是,经过数小时的调试后,我发现树的值始终为 0。我对为什么树的值为 0 感到困惑。我已经完成了大量的打印语句(其中一些我在发布的代码中留下了下面),我似乎无法确定为什么会发生这种情况。有人可以将我推向正确的方向吗?我想也许该函数在退出时正在删除变量,为了解决问题,我让 preorder 函数返回树(如下所示),但是,树的输出始终为 0。

代码:

typedef struct node
{
    // Each node holds a single integer.
    int data;

    // Pointers to the node's left and right children.
    struct node *left, *right;
} node;
int tree_diff(node *a, node *b)
{
    if (a == NULL && b == NULL)
        return 0;

    else if (a == NULL || b == NULL)
        return 1;


    else if (a->data != b->data)
        return 1;
    printf("A %d , B %d", a->data, b->data);

        return tree_diff(a->left, b->left) || tree_diff(a->right, b->right);
}

node *preorder_recursive(node *root, node *A)
{
    if (root == NULL)
        return A;

    printf("root %d ", root->data);
    A = root;
    printf("= data %d\n", A->data);
    preorder_recursive(root->left, A->left);
    preorder_recursive(root->right, A->right);
}

void postorder_recursive(node *root, node *B)
{
    if (root == NULL)
        return;
    B = root;
    postorder_recursive(root->left, B->left);
    postorder_recursive(root->right, B->right);
    printf("root %d ", root->data);
    printf("= data %d\n", B->data);
}

int kindredSpirits(node *a, node *b)
{

  // Get the preorder of a
  node *A = malloc(sizeof(node));
  A = preorder_recursive(a, A);

  // Get the postorder of b
  printf("\n\n");
  node *B = malloc(sizeof(node));
  postorder_recursive(b, B);

if(tree_diff(A,B) == 1)
  return 0;
else
  return 1;
}

测试用例:

#include <stdio.h>
#include <stdlib.h>
#include "KindredSpirits.h"
  node *create_node(int data)
{
    node *n = malloc(sizeof(node));

    n->data = data;
    n->left = n->right = NULL;

    return n;
}

node *forest_fire(node *root)
{
    if (root == NULL)
        return NULL;

    forest_fire(root->left);
    forest_fire(root->right);
    free(root);
}

int main(void)
{
    node *root;

    root = create_node(23);
    root->left = create_node(12);
    root->left->left = create_node(5);
    root->left->right = create_node(18);
    root->right = create_node(71);
    root->right->right = create_node(56);

    printf("%s\n", !kindredSpirits(root, root) ? "Success!" : "fail whale :(");

    forest_fire(root);

    return 0;
}

【问题讨论】:

  • 为什么要把两个参数传给preorder_recursivepostorder_recursive?我跟不上你的逻辑……可以简单的实现void preorder_recursive(node *root){ if (root != NULL) { printf("root %d ", root-&gt;data); preorder_recursive(root-&gt;left); preorder_recursive(root-&gt;right);} }
  • @Arash 我正在尝试将第一棵树的前序横向保存为第二棵树,以便将其与其他后序进行比较,看看这些树是否相同。我认为通过发送两个参数,我可以横向穿过两棵树,将第一棵树的值保存到第二棵树中,然后在获得一个的前序和另一个的后序之后,我可以检查两个生成的树是否相等.
  • 你的最终目标是什么?你想写一个函数来比较两棵树吗?
  • @Arash 我正在尝试编写一个函数来确定树 a 的前序是否等于树 b 的后序而不改变 a 或 b。这就是为什么我试图将横向值保存到不同的树。
  • 您的preorder_recursive 返回一个指针,但底部什么也不返回。在您的两个递归函数中,您检查root 是否为NULL,但随后您会检查A = root 和/或B = root(即吹走您需要的值)。如果你这样做了,在任何一个函数中都不需要第二个参数。

标签: c binary-search-tree preorder postorder


【解决方案1】:

下面是一个可以帮助您入门的代码片段:

typedef struct node {
    // Each node holds a single integer.
    int data;

    // Pointers to the node's left and right children.
    struct node *left,
    struct node *right;
} node;

typedef struct list {
    int lst_max;                        // maximum number of allocated cells
    int lst_cur;                        // current number of filled cells
    int *lst_base;                      // traversal list
} list;

list list_a = { 0, 0, NULL };
list list_b = { 0, 0, NULL };

void
list_append(list *lst,int data)
{
    int newidx;

    newidx = lst->lst_cur;

    if (newidx >= lst->lst_max) {
        lst->lst_max += 100;
        lst->lst_base = realloc(lst->lst_base,sizeof(int) * lst->lst_max);
        if (lst->lst_base == NULL) {
            printf("list_append: malloc error\n");
            exit(1);
        }
    }

    lst->lst_base[newidx] = data;

    lst->lst_cur = newidx + 1;
}

void
preorder_recursive(node *root,list *lst)
{

    if (root == NULL)
        return;

    list_append(lst,root->data);
    preorder_recursive(root->left,lst);
    preorder_recursive(root->right,lst);
}

void
postorder_recursive(node *root,list *lst)
{

    if (root == NULL)
        return;

    postorder_recursive(root->left,lst);
    postorder_recursive(root->right,lst);
    list_append(lst,root->data);
}

int
main(void)
{

    preorder_recursive(a,&list_a);
    postorder_recursive(b,&list_b);

    // compare list_a and list_b ...

    return 0;
}

【讨论】:

    【解决方案2】:

    我正在尝试编写一个函数来确定树 a 的前序是否等于树 b 的后序而不改变 a 或 b。

    我用数组保存遍历,然后比较两个数组的值。

    #define MAX_TREE_SIZE 100
    
    void preorder_recursive(node *root, int* arr, int *len) {
      if (root != NULL){
        arr[(*len)++] = root->data;
        preorder_recursive(root->left, arr, len);
        preorder_recursive(root->right, arr, len);
      }
    }
    
    void postorder_recursive(node *root, int *arr, int *len) {
      if (root != NULL){
       postorder_recursive(root->left, arr, len);
       postorder_recursive(root->right, arr, len);
       arr[(*len)++] = root->data;
      }
    }
    
    int kindredSpirits(node *a, node *b){
    
     // Get the preorder of a
     int *arr1 = malloc(MAX_TREE_SIZE * sizeof(int));
     int len1 = 0;
     preorder_recursive(a, arr1, &len1);
    
     // Get the postorder of b
     int *arr2 = malloc(MAX_TREE_SIZE * sizeof(int));
     int len2 = 0;
     postorder_recursive(b, arr2, &len2);
    
     int ret = 0; // 2 traversals are equal
     if (len1 != len2) {
        ret = 1;
     } else {
       for (int i = 0; i < len1; i++){
         if (arr1[i] != arr2[i]){
           ret = 1;
           break;
         }
       }
     }
    
     free(arr1);
     free(arr2);
     return ret;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-23
      • 2018-11-06
      • 2022-06-27
      • 1970-01-01
      相关资源
      最近更新 更多