Список не заполнен - PullRequest
       106

Список не заполнен

1 голос
/ 02 мая 2020

Я написал метод, который переворачивает список, но в результате список остается пустым. Помогите нам понять, в чем проблема.

Способ перевернуть список:

void reverseList(pLIST pL){
    pNODE pN = pL->top;
    pLIST pLReverse = createList();

    while(pN){
        pNODE pNew = malloc(sizeof(NODE));
        pNew->value = pN->value;
        if(!pLReverse->top){
            pNew->next = NULL;
            pLReverse->top = pNew;
        }
        else{
            pNew->next = pLReverse->top;
            pLReverse->top = pNew;              
        }

        pN = pN->next;
    }

    showList(pLReverse);
}

Структура списка:

typedef struct Node{
    int value;
    struct Node * next;
} NODE, *pNODE;

typedef struct List{
    int len;
    pNODE top;
} LIST, *pLIST;

Способ печати списка:

void showList(pLIST pL){
    if(isEmpty(pL)) printf("Empty\n");
    else{
        pNODE temp = pL->top;
        printf("Length: %d\n", pL->len);
        while(temp){
            printf("Pointer: %p\tValue: %d\tNext pointer: %p\n", temp, temp->value, temp->next);
            temp = temp->next;
        }
    }
}

1 Ответ

1 голос
/ 02 мая 2020

Для начала было бы плохой идеей вводить псевдонимы для таких указателей, как этот

typedef struct List{
    int len;
    pNODE top;
} LIST, *pLIST;

Используя такой псевдоним, вы, например, не можете объявить указатель на список констант, потому что это объявление

const pLIST list;

не означает то же самое, что

const struct List *list;

Вместо этого оно означает

struct List * const list;

Это не то, что требуется.

С учетом этого заявления

pLIST pLReverse = createList();

кажется, что вы распределяете списки динамически. Там нет необходимости делать это. Списки могут быть объявлены как объекты с автоматическим c сроком хранения.

Функция reverseList должна полностью перевернуть переданный ей список, а не создавать новый список внутри функции. Кроме того, у вас есть утечка памяти, потому что созданный список, на который указывает указатель pLReverse, не освобожден.

Вот демонстрационная программа, которая показывает, как можно определить функцию reverseList.

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

typedef struct Node
{
    int value;
    struct Node *next;
} Node;

typedef struct List
{
    size_t len;
    Node *head;
} List;

void init( List *list )
{
    list->len = 0;
    list->head = NULL;
}

int pushFront( List *list, int value )
{
    Node *new_node = malloc( sizeof( Node ) );

    int success = new_node != NULL;

    if ( success )
    {
        new_node->value = value;
        new_node->next = list->head;
        list->head = new_node;
        ++list->len;
    }

    return success;
}

void showList( const List *list )
{
    for ( Node *current = list->head; current != NULL; current = current->next )
    {
        printf( "%d -> ", current->value );
    }

    puts( "null" );
}

void reverseList( List *list )
{
    Node *current = list->head;
    list->head = NULL;

    while (  current != NULL )
    {
        Node *new_node = current;
        current = current->next;
        new_node->next = list->head;
        list->head = new_node;
    }
}

void freeList( List *list )
{
    while ( list->head != NULL )
    {
        Node *tmp = list->head;
        list->head = list->head->next;
        free( tmp ); 
    }
}

int main(void) 
{
    List list;
    init( &list );

    const int N = 10;

    for ( int i = 0; i < N; i++ )
    {
        pushFront( &list, i );
    }

    showList( &list );

    reverseList( &list );

    showList( &list );

    freeList( &list );

    return 0;
}

Вывод программы:

9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> null
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
...