c++ 你好!我的算法对n>7不起作用,我不知道为什么

iugsix8n  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(107)

我用BUILD_TREE建立了一个完美平衡的树,并使用PRETTY_PRINT将其打印出来。我的树的键在一个名为arr的排序数组中,我使用n作为键的个数。如果我给予n一个大于7的值,它不会打印任何东西,我不明白为什么。我需要它在n=11时工作。

#include <stdio.h>
#include <stdlib.h>     
#define NR_SPATII 7
#define MAX_SIZE 20
using namespace std;

typedef struct Tree {
    int key;
    struct Tree* left;
    struct Tree* right;
    int size;
}Tree;

Tree* createNewNode(int givenkey)
{
    Tree* node = (Tree*)malloc(sizeof(Tree));
    node->key = givenkey;
    node->left = NULL;
    node->right = NULL;
    node->size = NULL;
    return node;
}

Tree* BUILD_TREE(int arr[], int low, int high)
{
    int s = 1;
    if (low > high)
        return NULL;

    int mid = (low + high) / 2;
    Tree* node = createNewNode(mid);
    node->left = BUILD_TREE(arr, low, mid - 1);
    node->right = BUILD_TREE(arr, mid + 1, high);

    if (low == high)
        node->size = 1;
    else node->size = node->left->size + node->right->size + 1;

    return node;
}

void PRETTY_PRINT(Tree* root, int nivel)
{
    if (root == NULL)
        return;
    nivel += NR_SPATII; //crestem distanta intre nivele
    PRETTY_PRINT(root->right, nivel);//procesam copilul drept
    printf("\n");
    for (int i = NR_SPATII; i < nivel; i++)
        printf(" ");
    printf("%d,%d\n", root->key, root->size);//scriem nodul dupa spatiu
    PRETTY_PRINT(root->left, nivel);
}

void inOrder(Tree* root)
{
    if (root != NULL) {
        inOrder(root->left);
        printf("%d,%d  ", root->key, root->size);
        inOrder(root->right);
    }
}

void demo()
{
    int n = 7;
    int arr[MAX_SIZE];
    for (int i = 1; i <= n; i++)
        arr[i] = i;

    Tree* root = (Tree*)malloc(sizeof(Tree));
    root = BUILD_TREE(arr, 1, n);
    printf("AFISARE INORDINE:\n");
    inOrder(root);
    printf("\nAFISARE PRETTY PRINT:");
    PRETTY_PRINT(root, 0);
}

int main()
{
    demo();

    return 0;
}
6uxekuva

6uxekuva1#

在调试器中运行程序应该会立即将问题识别为BUILD_TREE中的这一行:

else node->size = node->left->size + node->right->size + 1;

问题是leftright指针可以为NULL。如果它们为NULL,则很可能会崩溃。取消引用NULL指针并阅读(或写入)该内存是未定义的行为。
您可以将其替换为:

if (low == high)
    node->size = 1;
else node->size = node->left->size + node->right->size + 1;

有了这个:

node->size = 1
    + (node->left ? node->left->size : 0)
    + (node->right ? node->right->size : 0);

这意味着如果一个子树为NULL,它将被视为大小为零,并且关键的是,您将不会取消引用该指针。
或者,您可以定义一个函数,返回树大小并在内部处理NULL测试:

int TreeSize(const Tree* tree)
{
    return tree ? tree->size : 0;
}

这样,您的计算就变得更简洁了:

node->size = 1 + TreeSize(node->left) + TreeSize(node->right);

相关问题