С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
PoisonFlame
0 / 0 / 0
Регистрация: 11.04.2012
Сообщений: 34
1

Удаление и редактирование элемента в двусвязном списке

20.04.2017, 16:24. Просмотров 327. Ответов 7

Не люблю создавать темы. Но объясните мне на пальцах (на моем примере) как правильно удалить и отредактировать элемент в списке (2 разные ф-ции), ну или ткните в ошибку..
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#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 часа 59 минут
2 ошибки нашла

C
1
2
printf("Страна: ");
scanf("%s", country);
а не
C
1
2
printf("Страна: ");
scanf("%s", pn->country);
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.04.2017, 16:24
Ответы с готовыми решениями:

Удаление элемента в двусвязном кольцевом списке
Добрый вечер! Сразу к телу: список двусвязный кольцевой. С помощью поиска...

Замена элемента в двусвязном списке
Помогите пожалуйста реализовать замену элемента в двусвязном списке. Например...

Удаление элемента в списке
Проблема: нужно удалить элемент, но я не понимаю как связать то, что я введу...

Удаление элемента в Списке
В чём ошибка функции удаления элемента. #include &lt;stdio.h&gt; #include...

Сортировка char в двусвязном списке
Добрый вечер! Облазил форумы..пробовал исправлять под разные примеры, а...

7
PoisonFlame
0 / 0 / 0
Регистрация: 11.04.2012
Сообщений: 34
23.04.2017, 23:49  [ТС] 2
В общем.
Разобралась с редактированием элемента списка и даже почти с удалением. В удалении никак не могу додуматься как удалить второй элемент, любой другой удаляется без проблем.
Вот код, может подскажет кто-то

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void del(struct ta *p)
{
    struct ta *pn,*temp;
    temp=(struct ta*)malloc(sizeof(struct ta));
    char country[128]; // – Строка для удаляемой страны
    printf("Страна: ");
    scanf("%s", country);
    pn = head;
    while(pn!=NULL){
        if(strcmp((pn->country),country)==0)
        {
                if(pn==head){
                    head=head->next;
                    if(head)
                        head->prev=NULL;
                    else
                        tail=NULL;
                    if(temp==pn)
                        temp=head;
                    free(pn);
                    break;
                }
                if (pn==tail)
                {
                    tail=tail->prev;
                    if(tail)
                        tail->next=NULL;
                    if(temp==pn)
                        temp=tail;
                    free(pn);
                    break;
                }
                else
                {
                    pn->next->prev=pn->prev;
                    if(pn->next)
                    pn->prev->next=pn->next;
                    free(pn);
                }
        }
        pn=p->next;
    }
   getch();
}
0
likehood
981 / 826 / 395
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
24.04.2017, 08:50 3
Цитата Сообщение от PoisonFlame Посмотреть сообщение
void del(struct ta *p)
Что такое p? Какой смысл имеет присваивание pn=p->next; в конце цикла?
Цитата Сообщение от PoisonFlame Посмотреть сообщение
C
1
2
3
4
5
6
7
                else
                {
                    pn->next->prev=pn->prev;
                    if(pn->next)
                    pn->prev->next=pn->next;
                    free(pn);
                }
Проверка if(pn->next) здесь не нужна, поскольку pn - это не начало и не конец списка, а значит pn->next не может быть равно NULL.
0
PoisonFlame
0 / 0 / 0
Регистрация: 11.04.2012
Сообщений: 34
24.04.2017, 10:26  [ТС] 4
p - указатель на первую структуру

я так понимаю, что мне нужно проверить является ли предыдущий элемент первым и.. что-то я совсем запуталась
0
likehood
981 / 826 / 395
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
24.04.2017, 11:12 5
Цитата Сообщение от PoisonFlame Посмотреть сообщение
я так понимаю, что мне нужно проверить является ли предыдущий элемент первым
Зачем?
0
PoisonFlame
0 / 0 / 0
Регистрация: 11.04.2012
Сообщений: 34
24.04.2017, 11:55  [ТС] 6
да потому что я не могу понять почему не удаляется именно второй элемент, первый, третий, последний удаляются без проблем, но второй никак. где я накосячила? (ответ, что "полезла в си" не принимается). Я до списков дошла неделю назад только, еще не очень в них
0
likehood
981 / 826 / 395
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
24.04.2017, 12:20 7
Цитата Сообщение от PoisonFlame Посмотреть сообщение
первый, третий, последний удаляются без проблем
Судя по коду проблемы должны быть. Из-за 41 строки (кстати, в первой программе она выглядит иначе).

Добавлено через 14 минут
Поскольку переменная pn в цикле не меняется (точнее, меняется один раз), мы должны получить вечный цикл. Здесь проблема не во втором элементе, а в логике работы цикла.
1
PoisonFlame
0 / 0 / 0
Регистрация: 11.04.2012
Сообщений: 34
24.04.2017, 23:56  [ТС] 8
В общем, я ничего не поняла, но дописала и все работает
Спасибо большое за волшебный пендель
0
24.04.2017, 23:56
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.04.2017, 23:56

Бинарный поиск в двусвязном списке
Кто-нибудь знает, как использовать бинарный поиск на двусвязных списках?

Удаление и поиск элемента в односвязном списке
Вот мои функции, но они почему то не работают: функция удаления удаляет всегда...

Нахождение числа в двусвязном кольцевом списке
Hallo! Следовало бы в работе настроить поиск цифрки. void search(){ int b;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru