Удаление и редактирование элемента в двусвязном списке - C (СИ)
Формулировка задачи:
Не люблю создавать темы. Но объясните мне на пальцах (на моем примере) как правильно удалить и отредактировать элемент в списке (2 разные ф-ции), ну или ткните в ошибку..
а не
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <locale.h> #include <string.h> #include <conio.h> struct ta { char country[128]; int id, count, days; double price; struct ta* next; struct ta* prev; }; struct ta *head, *tail; void create(void); // создание void list(struct ta *); // просмотр void del(struct ta *); // удаление void edit(struct ta *p); void create(void) { struct ta *p,*pred; pred=NULL; p=(struct ta *)malloc(sizeof(struct ta)); printf("Введите страну: "); scanf("%s", p->country); printf("Введите продолжительность: "); scanf("%d", &p->days); printf("Введите стоимость: "); scanf("%lf", &p->price); printf("Введите количество проданных: "); scanf("%d", &p->count); p->prev=pred; if (pred != NULL) { pred->next=p; } else { head = p; pred = p; } puts(" Закончить - <esc>"); tail=p; tail->next=NULL; system("cls"); } void add(struct ta *p) { struct ta *pn,*pred; pn=(struct ta *)malloc(sizeof(struct ta)); // pn – указатель на новую структуру printf("Введите страну: "); scanf("%s", pn->country); printf("Введите продолжительность: "); scanf("%d", &pn->days); printf("Введите стоимость: "); scanf("%lf", &pn->price); printf("Введите количество проданных: "); scanf("%d", &pn->count); pn->prev=NULL; pn->next=p; p->prev=pn; head=pn; } void list(struct ta *p) { if (p==head) while (p != NULL) { printf("%s", p->country); printf("%d", p->days); printf("%lf", p->price); printf("\n"); printf("%d", p->count); p=p->next; } else if (p==tail) while ( p!= NULL) { printf("%s", p->country); printf("%d", p->days); printf("%lf", p->price); printf("\n"); printf("%d", p->count); p=p->prev; } else puts("Неверный адрес "); } void del(struct ta *p) { struct ta *pn,*temp; char country[128]; // – Строка для удаляемой страны printf("Страна: "); scanf("%s", pn->country); pn=head; while (pn!=NULL) { if (strcmp((pn->country),country)==0) // если найдена заданная страна { if (pn==head) // если найденная запись - первая { head=pn->next; head->prev=NULL; free(pn); pn=head; } else if (pn==tail) // если найденная запись - последняя { tail=pn->next; tail->next=NULL; free(pn); pn=tail; } else // удаление из средины списка { pn->next->prev=pn->prev; pn->prev->next=pn->next; temp=pn; pn=pn->next; free(temp); } } else // если заданная страна не найдена – продвигаемся по списку p=pn->next; } } void edit(struct ta *p) { struct ta *pn,*temp; char country[128]; // – Строка для удаляемой страны printf("Страна: "); scanf("%s", pn->country); pn=head; while (pn!=NULL) { if (strcmp((pn->country),country)==0) // если найдена заданная страна { printf("Введите страну: "); scanf("%s", pn->country); printf("Введите продолжительность: "); scanf("%d", &pn->days); printf("Введите стоимость: "); scanf("%lf", &pn->price); printf("Введите количество проданных: "); scanf("%d", &pn->count); } else p=pn->next; } } void main() { setlocale(LC_ALL, "Russian"); int key; do { system("cls"); printf("1. Показать все\n" ); printf("2. Добавить\n"); printf("3. Редактировать\n"); printf("4. Удалить\n"); printf("9. Создать \n"); printf("0. Выход \n"); scanf("%d", &key); switch (key) { case 1: list(head); break; case 2: add(head); break; case 3: edit(head); break; case 4: del(head); break; case 0: return 0; break; } } while (key!=27); }
2 ошибки нашла
printf("Страна: "); scanf("%s", country);
printf("Страна: "); scanf("%s", pn->country);
Решение задачи: «Удаление и редактирование элемента в двусвязном списке»
textual
Листинг программы
else { pn->next->prev=pn->prev; if(pn->next) pn->prev->next=pn->next; free(pn); }
Объяснение кода листинга программы
В представленном коде выполняется освобождение памяти, выделенной под узел двусвязного списка, в случае, если данный узел является последним в списке. При выполнении кода происходит следующее:
pn
— указатель на узел, который необходимо удалить.pn->next
— указатель на следующий узел в списке, инициализируется значениемpn->prev
(указатель на предыдущий узел).pn->prev->next
— указатель на следующий узел после удаляемого, инициализируется значениемpn->next
(указатель на следующий узел).free(pn)
— выделение памяти под узлом освобождается. В итоге представленный код выполняет удаление узла из двусвязного списка.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д