Двунаправленный список - ошибка где-то в коде - C (СИ)
Формулировка задачи:
Пытался разобрать пример, переписал, всё запускается, но, когда пытаюсь ввести символ, вылетает.
Всё 3 раза перепроверил, так и не смог понять в чём проблема.
HELP
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
typedef struct item {
char data;
struct item *next;
struct item *previous;
} Item;
void insert(char value);
void cut(char value);
void display(void);
item *head = NULL, *tail=NULL;
#define FALSE 0
#define TRUE 1
int main()
{
int done = FALSE;
char c, value;
while (!done) {
display();
printf("\n\nA)dd, D)elete, Q)uit\n\n");
c = _getch();
switch (toupper(c)) {
case 'A':
printf("\nEnter the character: ");
value = _getch();
insert(value);
break;
case 'D':
if (head != NULL) {
printf("\n Enter the chatacter to be deleted: ");
value = _getch();
cut(value);
}
break;
case 'Q':
done = TRUE;
break;
}
}
return 0;
}
void insert(char value)
{
item *p, *current = head;
p = (item *)malloc(sizeof(Item));
p->data = value;
p->next = p->previous = NULL;
if (head = NULL) {
head = tail = p;
return;
}
while (current != NULL && value > current->data)
current = current->next;
if (current == head) {
p->next = head;
head->previous = p;
head = p;
}
else if (current == NULL) {
tail->next = p;
p->previous = tail;
p->next = NULL;
tail = p;
}
else {
current->previous->next = p;
p->previous = current->previous;
current->previous = p;
p->next = current;
}
}
void cut(char value)
{
item* p=head;
while (p != NULL && p->data != value)
p = p->next;
if (p == NULL)
return;
if (p == head){
head = head->next;
head->previous = NULL;
}
else if (p == tail) {
tail = tail->previous;
tail->next = NULL;
}
else {
p->previous->next = p->next;
p->next->previous = p->previous;
}
free(p);
}
void display(void)
{
item* p = head;
system("cls");
if (p == NULL)
puts("List is empty\n");
else {
printf("NULL <-> ");
while (p != NULL) {
printf("%c <-> ", p->data);
p = p->next;
}
printf("NULL");
}
}Решение задачи: «Двунаправленный список - ошибка где-то в коде»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct item {
char data;
struct item *next;
struct item *previous;
} Item;
void insert(char value);
void cut(char value);
void display(void);
Item *head = NULL, *tail=NULL;
#define FALSE 0
#define TRUE 1
int main()
{
int done = FALSE;
char c, value;
while (!done) {
display();
printf("\n\nA)dd, D)elete, Q)uit\n\n");
c = getchar();
switch (toupper(c)) {
case 'A':
printf("\nEnter the character: ");
value = getchar();
insert(value);
break;
case 'D':
if (head != NULL) {
printf("\n Enter the chatacter to be deleted: ");
value = getchar();
cut(value);
}
break;
case 'Q':
done = TRUE;
break;
}
}
return 0;
}
void insert(char value)
{
Item *p, *current = head;
p = (Item *)malloc(sizeof(Item));
p->data = value;
p->next = p->previous = NULL;
if (head == NULL) {
head = tail = p;
return;
}
while (current != NULL && value > current->data)
current = current->next;
if (current == head) {
p->next = head;
head->previous = p;
head = p;
}
else if (current == NULL) {
tail->next = p;
p->previous = tail;
p->next = NULL;
tail = p;
}
else {
current->previous->next = p;
p->previous = current->previous;
current->previous = p;
p->next = current;
}
}
void cut(char value)
{
Item* p=head;
while (p != NULL && p->data != value)
p = p->next;
if (p == NULL)
return;
if (p == head){
head = head->next;
head->previous = NULL;
}
else if (p == tail) {
tail = tail->previous;
tail->next = NULL;
}
else {
p->previous->next = p->next;
p->next->previous = p->previous;
}
free(p);
}
void display(void)
{
Item* p = head;
system("cls");
if (p == NULL)
puts("List is empty\n");
else {
printf("NULL <-> ");
while (p != NULL) {
printf("%c <-> ", p->data);
p = p->next;
}
printf("NULL");
}
}
Объяснение кода листинга программы
- Объявлены структуры и переменные:
- Структура
Itemпредставляет собой двунаправленный связный список с элементами типаchar. - Переменные
headиtailуказывают на начало и конец списка. - Переменная
doneотслеживает, завершена ли работа программы. - Переменная
cиспользуется для получения ввода от пользователя. - Переменная
valueиспользуется для хранения значения, введенного пользователем.
- Структура
- В функции
main()реализована последовательность действий:- Пользователю предлагается ввести данные, пока список не будет пуст.
- Выводится меню с тремя вариантами действий: добавить элемент, удалить элемент, выйти из программы.
- В зависимости от выбора пользователя выполняется соответствующая функция.
- Если пользователь выбирает
выход, переменнаяdoneустанавливается вTRUE, и программа завершается.
- В функции
insert()реализована логика добавления элемента в двунаправленный связный список:- Создается новый элемент списка.
- Если список пуст, новый элемент становится и головой, и хвостом списка.
- Если список не пуст, новый элемент добавляется в конец списка.
- Для добавления элемента в середину списка используется алгоритм вставки в связный список.
- В функции
cut()реализована логика удаления элемента из двунаправленного связного списка:- Находится элемент, который нужно удалить.
- Если удаляемый элемент является головой списка, он заменяется на следующий элемент.
- Если удаляемый элемент является хвостом списка, он заменяется на предыдущий элемент.
- Если удаляемый элемент находится в середине списка, его связь с предыдущим и следующим элементами обновляется.
- Удаленный элемент освобождается с помощью функции
free().
- В функции
display()реализована логика вывода содержимого двунаправленного связного списка:- Если список пуст, выводится сообщение
Список пуст. - Иначе, выводится сообщение
NULL <->и последовательность элементов списка, завершающаяся сообщениемNULL.
- Если список пуст, выводится сообщение