Удаление и редактирование элемента в двусвязном списке - 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)— выделение памяти под узлом освобождается. В итоге представленный код выполняет удаление узла из двусвязного списка.