Двунаправленный список - ошибка где-то в коде - 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");
    }
}

Объяснение кода листинга программы

  1. Объявлены структуры и переменные:
    • Структура Item представляет собой двунаправленный связный список с элементами типа char.
    • Переменные head и tail указывают на начало и конец списка.
    • Переменная done отслеживает, завершена ли работа программы.
    • Переменная c используется для получения ввода от пользователя.
    • Переменная value используется для хранения значения, введенного пользователем.
  2. В функции main() реализована последовательность действий:
    • Пользователю предлагается ввести данные, пока список не будет пуст.
    • Выводится меню с тремя вариантами действий: добавить элемент, удалить элемент, выйти из программы.
    • В зависимости от выбора пользователя выполняется соответствующая функция.
    • Если пользователь выбирает выход, переменная done устанавливается в TRUE, и программа завершается.
  3. В функции insert() реализована логика добавления элемента в двунаправленный связный список:
    • Создается новый элемент списка.
    • Если список пуст, новый элемент становится и головой, и хвостом списка.
    • Если список не пуст, новый элемент добавляется в конец списка.
    • Для добавления элемента в середину списка используется алгоритм вставки в связный список.
  4. В функции cut() реализована логика удаления элемента из двунаправленного связного списка:
    • Находится элемент, который нужно удалить.
    • Если удаляемый элемент является головой списка, он заменяется на следующий элемент.
    • Если удаляемый элемент является хвостом списка, он заменяется на предыдущий элемент.
    • Если удаляемый элемент находится в середине списка, его связь с предыдущим и следующим элементами обновляется.
    • Удаленный элемент освобождается с помощью функции free().
  5. В функции display() реализована логика вывода содержимого двунаправленного связного списка:
    • Если список пуст, выводится сообщение Список пуст.
    • Иначе, выводится сообщение NULL <-> и последовательность элементов списка, завершающаяся сообщением NULL.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 3.833 из 5
Похожие ответы