Проблемы с итератором списка ADT в C

я делаю ADT List Iterator в C. Когда я использую примитив для печати списка в начало, они работают правильно. Но затем, внутри основного, я хочу создать итератор по списку и посмотреть, работает ли примитив удаления (я не работает правильно), но затем я хочу снова распечатать список с помощью print_list_iterator(), это не работает. У меня есть такие структуры:

typedef struct node{
    struct node *next;
    void *data;
}nodo_t;

typedef struct list{
    struct node *head;
}list_t;

typedef struct iterator{
    node_t **pn;
}list_iterator_t;

Это примитивы ADT Iterator, с которыми я работаю;

list_iterator_t * list_iterator_create(list_t * l){
    struct iterator *li = malloc(sizeof(struct iterator));
    if (li == NULL)
        return NULL;
    li->pn = &(l->head);
    return li;
}

bool list_iterator_next(list_iterator_t *li){
    if (*li->pn == NULL){
        return false;
    }
    *li->pn = (*li->pn)->next;
    return true;
}
void *list_iterator_current(const list_iterator_t *li){
    if ((*li->pn) == NULL){
        return NULL;
    }
    return (*li->pn)->data;
}

Вот мой примитив для удаления итератора;

void *list_iterator_delete(lista_iterator_t *li){

    if (*li->pn == NULL)
        return NULL;

    struct node *aux;
    void *aux_data = (*li->pn)->data;

    aux = (*li->pn);
    *li->pn = (*li->pn)->next;

    free(aux);
    return aux_data;
}

Затем, если я хочу распечатать список, который я использую:

void print_list_iterator(lista_t * l){

    for(list_iterator_t *li =list_iterator_create(l);
        !list_iterator_finish(li);
        list_iterator_next(li)
        ){
        int *e = list_iterator_current(li);
        printf("%d -> ",*e);
    }
}

Если я использую print_list_iterator(), то в основном это не позволяет мне создать итератор в том же списке и использовать мои примитивы. Любые идеи? Кстати, хотелось бы узнать, хорошо ли реализованы эти примитивы.

Функциональный тест в основном: интервал основной () {

  list_t *dest = list_create();
    list_iterator_t *iter = list_iterator_create(dest);
    int vector[] = {88,99,1,0,5,106,22,44,56,3,5,6,3,4,6};
        size_t vector_size = sizeof(vector)/sizeof(vector[0]);
        for(size_t i=0; i<vector_size; i++)
            list_append(dest, vector +i);
        list_iterator_delete(iter);
        list_iterator_delete(iter);
        list_iterator_delete(iter);
        list_iterator_delete(iter);
        print_list_iterator(dest);

В терминале:

   MacBook-Air: UltraT$ gcc iterator_double_pointers.c -std=c99 -Wall -pedantic -o it2
    MacBook-Air: UltraT$ ./it2
    5 -> 106 -> 22 -> 44 -> 56 -> 3 -> 5 -> 6 -> 3 -> 4 -> 6 -> 

Итак, моя функция работает правильно, но: Если я вызываю функцию печати (которая на самом деле является функцией, которая проходит через список с примитивами итератора, поэтому я поделился примитивами итератора, поскольку там может быть какая-то ошибка)

    print_list_iterator(destino);
    list_iterator_delete(iter);
    print_list_iterator(destino);
    list_iterator_delete(iter);
    list_iterator_delete(iter);
    list_iterator_delete(iter);

Результат в терминале:

MacBook-Air:tp2 UltraT$ ./it2
88 -> 99 -> 1 -> 0 -> 5 -> 106 -> 22 -> 44 -> 56 -> 3 -> 5 -> 6 -> 3 -> 4 -> 6 -> 

Это не работает.

Вот почему моя функция устранения иногда работает, а иногда нет. Я не знаю, где проблема, если в функции печати (которая фактически проходит по списку) или в функции удаления

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

Gene 27.07.2019 04:50

Гена имеет в виду этот минимальный воспроизводимый пример.

Yunnosch 27.07.2019 08:25

Буквально вчера был вопрос по этому поводу, воспользуйтесь поиском. Вам нужен указатель на указатель элемента prev в итераторе!

Antti Haapala -- Слава Україні 27.07.2019 13:06

@AnttiHaapala Да, вы правы насчет поста. Но здесь я не спрашиваю то же самое, здесь функция, которую я сделал, работает правильно (list_iterator_delete()), если я создаю итератор в списке в файле main. Затем, если я вызываю функцию print_list_iterator(), я могу печатать на экране, но после использования этой функции (которая создает мне еще один итератор в списке, который я прошу вас распечатать) я не могу использовать итератор в ранее созданном.

Renzo 27.07.2019 19:30

@Gene Да, ты прав, я попытаюсь обобщить свою проблему. Я подумал, что было бы неплохо показать всю имеющуюся у меня информацию, потому что моя проблема может заключаться в любом из примитивов. Если бы я разделял только функции print_list_iterator() и list_iterator_delete(), возможно, было бы мало информации для анализа проблемы.

Renzo 27.07.2019 19:33

Та же проблема, нужно перелинковать список по удаленному узлу

Antti Haapala -- Слава Україні 28.07.2019 08:22

@AnttiHaapala извините, но я вас не понимаю. Если можно, посмотрите на редакцию, которую я сделал к посту. Моя функция удаления работает (иногда). Я не знаю, проблема в устранении или просмотре списка (распечатать)

Renzo 28.07.2019 21:19

@Renzo: в вашей функции удаления после того, как вы удалили текущий узел, предыдущий узел по-прежнему будет указывать на теперь удаленный узел, или, если он был первым, голова все равно будет указывать на него.

500 - Internal Server Error 28.07.2019 22:07

@ 500-InternalServerError, не могли бы вы помочь мне с кодом?

Renzo 29.07.2019 15:24

Взгляните на этот пример для вдохновения (не мое).

500 - Internal Server Error 29.07.2019 16:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
127
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Наконец, я решил это, используя *prev и *curr(текущий узел). В будущем я хочу изменить функцию, чтобы использовать ее с двойными указателями.

struct list_iterator{

    node_t *prev;
    node_t *curr;
    list_t *l_iter;
};

typedef struct list_iterator list_iterator_t

void * delete_iterator_list(list_iterator_t * li) {

    if (list_iterator_finish (li))
        return NULL;

    struct node * aux_node;
    void * data;

    if (! li-> prev) {
        data = li-> curr-> data;
        aux_node = li-> curr;
        li-> l_iter-> head = aux_node-> next;
        li-> curr = li-> l_iter-> head;
    }
    else if (li-> curr-> next == NULL) {
        data = li-> curr-> data;
        aux_node = li-> curr;
        li-> curr = li-> curr-> next;
        li-> prev-> next = li-> curr;
    }
    else {
        data = li-> curr-> data;
        aux_node = li-> curr;
        li-> curr = li-> curr-> next;
        li-> prev-> next = li-> curr;
    }
    free (aux_node);
    return data;

Другие вопросы по теме