Удалить указанный c элемент связанный список - PullRequest
2 голосов
/ 07 мая 2020

Не могли бы вы помочь мне понять, почему эта функция не удаляет указанный c элемент в связанном списке? Что я делаю не так?

typedef struct str_node{
    int data;
    struct str_node *next;
}node;

...
node *head;
head = malloc(sizeof(node));
...

void delete_spec(node *a){
    int num;
    node *tmp;

    tmp = a;
    printf("Insert number to eliminate: ");
    scanf("%d",&num);
    while(tmp!=NULL){
        if(tmp->data == num){
            tmp = tmp->next->next;
        }
        tmp = tmp->next;
    }
}

Ответы [ 2 ]

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

Для начала неясно, что здесь происходит при выделении

node *head;
head = malloc(sizeof(node));

Головка указателя должна быть изначально установлена ​​в NULL

node *head = NULL;

и новые узлы должны быть вставлены в список функцией, которая вставляет новые значения в список.

Функция, удаляющая узлы из списка, не должна выдавать никаких подсказок. Это вызывающий объект функции, который попросит пользователя указать значение, которое будет удалено из списка, а затем вызовет функцию, передающую указанное значение. Таким образом, функция должна иметь два параметра: указатель на указатель на головной узел и целочисленное значение, которое необходимо удалить из списка.

Функцию можно определить следующим образом:

void delete_spec( node **head, int data )
{
    while ( *head != NULL )
    {
        if ( ( *head )->data == data )
        {
            node *tmp = *head;
            *head = ( *head )->next;
            free( tmp );
        }
        else
        {
            head = &( *head )->next;
        }
    }
}     

Вот демонстрационная программа.

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

typedef struct str_node
{
    int data;
    struct str_node *next;
} node;

int push_front( node **head, int data )
{
    node *new_node = malloc( sizeof( node ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->data = data;
        new_node->next = *head;
        *head = new_node;
    }

    return success;
}

void delete_spec( node **head, int data )
{
    while ( *head != NULL )
    {
        if ( ( *head )->data == data )
        {
            node *tmp = *head;
            *head = ( *head )->next;
            free( tmp );
        }
        else
        {
            head = &( *head )->next;
        }
    }
}

void display( node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->data );
    }

    puts( "null" );
}

int main(void) 
{
    node *head = NULL;
    int a[] = { 1, 3, 5, 7, 1, 2, 3, 1 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for ( size_t i = 0; i < N; i++ )
    {
        push_front( &head, a[i] );
    }

    display( head );

    delete_spec( &head, 1 );

    display( head );

    return 0;
}

Результат:

1 -> 3 -> 2 -> 1 -> 7 -> 5 -> 3 -> 1 -> null
3 -> 2 -> 7 -> 5 -> 3 -> null
0 голосов
/ 07 мая 2020

delete_spec никоим образом не изменяет список ввода. также: он не освобождает память.

для фактического удаления узла вы должны: 1. освободить его память. 2. Измените список так, чтобы «следующие» указатели обновлялись. чтобы обновить список, вы должны предоставить функции удаления адрес головы, чтобы она могла также изменять голову.

примерно так:

void delete_spec(node **a){
    int num;
    node *tmp;

    if (a == NULL || *a == NULL) return;

    tmp = *a;

    printf("Insert number to eliminate: ");
    scanf("%d",&num);

    if (tmp->data == num)
    {
        *a = (*a)->next;
        free(tmp);
        return;
    }


    while(tmp->next!=NULL){
        if(tmp->next->data == num){
            node* tmp2 = tmp->next;
            tmp->next = tmp->next->next;
            free(tmp2);
        }
        tmp = tmp->next;
    }
}
...