Освобождение предыдущего узла в связанном списке - PullRequest
0 голосов
/ 27 марта 2019

Я написал функцию для обхода связанного списка, поиска узла с наименьшим значением для 'intquency' и удаления этого узла, как только он прошел весь список. Моя ошибка исходит от узла: «предыдущая». Когда я запускаю код, я получаю сообщение об ошибке: «prev является нулевым указателем». Однако, если я удаляю часть '= NULL' из объявления узла, я получаю ошибку компиляции, которая гласит: "prev is неинициализирован".

Это потому, что мне нужно присвоить / указать предыдущую точку одному из существующих узлов в списке? Если так, то как бы я указал на этот узел перед тем, который я хочу удалить? (Я думал, что это было сделано так, как в моем коде, но, очевидно, нет.)

Определения структуры:

struct LetterFrequencyPair
{
    char character;
    int frequency;
    //Creating a pointer to point to the next child in the list
    struct BinaryTreeNode* next;
};

struct BinaryTreeNode
{
    //create a pointer to point to the LetterFrequencyPair
    struct LetterFrequencyPair* letter_frequency_pair;
    //create pointers to the children of the node
    struct BinaryTreeNode* leftChild;
    struct BinaryTreeNode* rightChild;
};

struct BinaryTreeNode* ret_lowestF()
{
    int val = 1000;
    struct LetterFrequencyPair* temp;
    struct LetterFrequencyPair* temp1 = NULL;
    struct LetterFrequencyPair* prev = NULL;
    struct LetterFrequencyPair* low = malloc(sizeof(struct 
    LetterFrequencyPair));

    struct BinaryTreeNode* lowest = malloc(sizeof(struct BinaryTreeNode));
    temp = root;
    if (temp == NULL)
    {
        printf("List is empty.\n");
    }
    else
    {
        while (temp != NULL)
        {
            printf("%c\t%d\n", temp->character, temp->frequency);

            if (val >> temp->frequency)
            {
                low = temp;
                lowest->letter_frequency_pair = low;
                val = low->frequency;
                temp1 = temp;
                prev->next = temp1;
            }

            temp = temp->next;
        }
    }
    prev->next = temp1->next;
    temp1->next = NULL;
    free(temp1);

    printf("lowest frequency node is: %c\t%d\n", low->character, low- 
            >frequency);

    return lowest;
}

1 Ответ

0 голосов
/ 27 марта 2019

Когда я запускаю код, я получаю сообщение об ошибке: «prev is null pointer».Однако, если я удаляю часть '= NULL' из объявления узла, я получаю ошибку компиляции, которая говорит: "prev is неинициализирован".

Хорошо, да.Хотя в нескольких местах вы пытаетесь присвоить prev->next, нигде вы не назначаете самому prev, если не хотите считать его инициализатор.Когда эта переменная равна NULL или вообще не имеет определенного значения, она не указывает ни на один объект.При таких обстоятельствах отсутствует prev->next.

Похоже, вы хотите использовать prev для отслеживания узла, предшествующего текущему минимуму.Это представляет небольшую проблему, когда головным узлом вашего списка является текущий минимум.Это можно обойти, установив prev в NULL в этом случае и написав дополнительный код для этого особого случая, но проще и чище обойти проблему, введя искусственный предшественник:

struct LetterFrequencyPair head = { .next = root };
struct LetterFrequencyPair *prev = &head;

Обратите внимание, что нет необходимости выделять головной узел динамически.В этом случае вам не нужно каких-либо динамических выделений.В настоящее время ваш код теряет память, которую он выделяет для low, на которую он изначально указывает, а выделение для lowest и освобождение исходного низшего узла является расточительным.удаление превращает наш быть первым.Вам не нужна специальная обработка для этого в точке удаления;в этом случае он должен выпадать естественным образом в том случае, если head.next установлено (через prev), чтобы указывать на новый первый узел.В конце, однако, вы захотите скопировать его обратно:

root = head.next;

Если первый узел не тот, который был удален, то это назначение не имеет чистого эффекта.

У вас много других проблем с вашим кодом, которые выходят далеко за рамки вопроса, но с этого стоит начать.

...