Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
edw1n
7 / 7 / 1
Регистрация: 12.11.2012
Сообщений: 114
#1

Удаление элемента из середины списка - C++

27.10.2013, 21:20. Просмотров 1655. Ответов 12
Метки нет (Все метки)

Приветствую. При написании программы возникла такая проблема. Не могу нормально удалить элемент, который находится в середине списка. У меня почему-то удаляет именно не текущий элемент, а следующий.

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
#include <stdio.h>
#include <conio.h>
#include <iostream>
 
typedef struct St
{
        int data;
        struct St *next;
        } element;
typedef element *ptr;
 
ptr AddElem (ptr head, int elem)
{
    ptr x;
    x=new element;
    x->data=elem;
    x->next=head;
    head=x;
    return head;
}
 
void Print (ptr head)
{
     ptr x=head;
     while (x!=NULL)
     {
           printf ("%d ", x->data);
           x=x->next;
     }
}
 
ptr DelElem (ptr *current)
{
    ptr x;
    x=(*current)->next;
    (*current)->next=(*current)->next->next;
    free (x);
    return *current;
}
 
int main (void)
{
    int n,i;
    printf ("Enter n: ");
    scanf ("%d", &n);
    ptr head=NULL, x, tmp;
    for (i=0; i<n; i++)
        head=AddElem(head,(n-i));
    Print(head);
    printf ("\n");
    x=head;
    x=x->next; //сейчас мы находимся на 2-ом элементе списка
    printf ("%d\n", x->data);
    for (i=1; i<=3; i++)
        {
              x=DelElem(&x); //так как мы находимся на 2-ом элементе списка, то после выполнения этой строки, подпрограмма должна удалить его, но удаляется почему-то 3-ий (следующий) элемент.
              printf ("%d: ", i); //вывод на экран номер итерации цикла for
              Print(head); //вывод на экран уже изменённого списка
              printf ("\n");
        }
    getch();
    return 0;
}
Если n положить 10, то на консоле мы увидим:
1 2 3 4 5 6 7 8 9 10
2
1: 1 2 4 5 6 7 8 9 10
2: 1 2 5 6 7 8 9 10
3: 1 2 6 7 8 9 10

Помогите, в чем проблема ? Подозреваю что проблема в указателях в подпрограмме DelElem, пытался по-разному её менять, но ни к чему хорошему это не привело. Спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
XRuZzz
Антикодер
649 / 550 / 27
Регистрация: 15.09.2012
Сообщений: 2,497
27.10.2013, 21:24     Удаление элемента из середины списка #2
Цитата Сообщение от edw1n Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
ptr DelElem (ptr *current)
{
...
x=(*current)->next;
...
free (x);
...
}
так вы и удаляете следующий
edw1n
7 / 7 / 1
Регистрация: 12.11.2012
Сообщений: 114
27.10.2013, 21:26  [ТС]     Удаление элемента из середины списка #3
Цитата Сообщение от XRuZzz Посмотреть сообщение
так вы и удаляете следующий
Убирал я этот next оттуда. Запускаю программу, а оно мне без остановки печатает цифры в консоли.
XRuZzz
Антикодер
649 / 550 / 27
Регистрация: 15.09.2012
Сообщений: 2,497
27.10.2013, 21:27     Удаление элемента из середины списка #4
C++
1
delete current;
вместо free используйте delete, хотите знать почему?
edw1n
7 / 7 / 1
Регистрация: 12.11.2012
Сообщений: 114
27.10.2013, 21:27  [ТС]     Удаление элемента из середины списка #5
Цитата Сообщение от XRuZzz Посмотреть сообщение
вместо free используйте delete, хотите знать почему?
Хочу знать.
С delete такая же беда.
XRuZzz
Антикодер
649 / 550 / 27
Регистрация: 15.09.2012
Сообщений: 2,497
27.10.2013, 21:58     Удаление элемента из середины списка #6
Цитата Сообщение от edw1n Посмотреть сообщение
Хочу знать.
так почитайте соответствующую Литература C++
но указатель на next в x вы сохраняли не просто так... тут нужно подумать

Цитата Сообщение от edw1n Посмотреть сообщение
С delete такая же беда.
часть ошибок исправили, дальше пусть другие вам помогают, код некрасиво написан, мне не очень хочется его читать.
edw1n
7 / 7 / 1
Регистрация: 12.11.2012
Сообщений: 114
27.10.2013, 22:01  [ТС]     Удаление элемента из середины списка #7
Удаление элемента из середины списка

Указатель current показывает на i-1 элемент. Нам нужно удалить i-й элемент. Для этого ему нужен указатель х.

C++
1
x=current->next;
Удаление элемента из середины списка

Дальше мы выполняем присваивание чтобы наш i-1 элемент указывал не на i-й, а на i+1 элемент.

C++
1
current->next=current->next->next;
Удаление элемента из середины списка

Я понял в чем моя ошибка, в функцию я отправляю указатель на i-й элемент, поэтому удаляется i+1. Как мне сделать чтобы я смог отправлять указатель на i-1 элемент ?
edw1n
7 / 7 / 1
Регистрация: 12.11.2012
Сообщений: 114
27.10.2013, 22:03  [ТС]     Удаление элемента из середины списка #8
Цитата Сообщение от XRuZzz Посмотреть сообщение
код некрасиво написан, мне не очень хочется его читать.
А не могли бы вы скинуть немного примеров с красивым кодом, если не сложно ? Я знаю что у меня с оформлением проблемы, его сложно читать другим людям и я работаю над решением этой проблемы.
XRuZzz
Антикодер
649 / 550 / 27
Регистрация: 15.09.2012
Сообщений: 2,497
27.10.2013, 23:12     Удаление элемента из середины списка #9
Цитата Сообщение от edw1n Посмотреть сообщение
А не могли бы вы скинуть немного примеров с красивым кодом, если не сложно ? Я знаю что у меня с оформлением проблемы, его сложно читать другим людям и я работаю над решением этой проблемы.
Нормальный код это код с использованием STL вам для изучения списков STL сейчас не подходит(но сразу после изучения списков и других базовых тем стоит переключаться на STL). У вас есть красивые картинки на них и нужно опираться, но правда они по ходу неверные - не ясно откуда вы взяли i -1.
У вас current это i а current->next это i + 1
edw1n
7 / 7 / 1
Регистрация: 12.11.2012
Сообщений: 114
27.10.2013, 23:16  [ТС]     Удаление элемента из середины списка #10
Цитата Сообщение от XRuZzz Посмотреть сообщение
Нормальный код это код с использованием STL вам для изучения списков STL сейчас не подходит(но сразу после изучения списков и других базовых тем стоит переключаться на STL). У вас есть красивые картинки на них и нужно опираться, но правда они по ходу неверные - не ясно откуда вы взяли i -1.
У вас current это i а current->next это i + 1
Вообще это не мой код, и картинки я оттуда срисовал. Это наша... методичка с заданиями. Там так было написано. Короче говоря, функция удаляет не поточный элемент на следующий. Завтра буду разбираться.
XRuZzz
Антикодер
649 / 550 / 27
Регистрация: 15.09.2012
Сообщений: 2,497
27.10.2013, 23:37     Удаление элемента из середины списка #11
Цитата Сообщение от edw1n Посмотреть сообщение
Вообще это не мой код, и картинки я оттуда срисовал. Это наша... методичка с заданиями. Там так было написано. Короче говоря, функция удаляет не поточный элемент на следующий. Завтра буду разбираться.
надо код исправлять, чтоб соответствовал картинкам. смысл такой, для удаления запоминаем указатель на следующий элемент, удаляем текущий, то что запомнили делаем следующим у предыщего элемента.

вот ещё что -> уже подразумевает что не нужно ставить "*"
поэтому достаточно писать current->next
edw1n
7 / 7 / 1
Регистрация: 12.11.2012
Сообщений: 114
27.10.2013, 23:40  [ТС]     Удаление элемента из середины списка #12
Цитата Сообщение от XRuZzz Посмотреть сообщение
вот ещё что -> уже подразумевает что не нужно ставить "*"
поэтому достаточно писать current->next
Да, я знаю. Я все время пробовал без "*".
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.10.2013, 00:05     Удаление элемента из середины списка
Еще ссылки по теме:
C++ Удаление элемента со списка
C++ Удаление элемента из списка
Удаление элемента из списка C++
Удаление элемента из двусвязного списка C++
C++ Удаление каждого M-го элемента списка

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

Или воспользуйтесь поиском по форуму:
XRuZzz
Антикодер
649 / 550 / 27
Регистрация: 15.09.2012
Сообщений: 2,497
28.10.2013, 00:05     Удаление элемента из середины списка #13
но даже если вы исправите, то функция будет называться не DelElem, а скорее deleteNext()

то есть удаляет не то, что ожидаете.

отсюда мне приходит в голову, что нужно сначала найти предыдущий элемент(i-1), пройдя весь список вперёд,
так как мы не можем определить его сразу по текущему элементу, а он нам нужен для удаления текущего

или более рационально, перед тем как найдёте элемент, который требуется удалить сохраняйте указатель на предыдущий (i-1) элемент.

помоему больше нет вариантов
Yandex
Объявления
28.10.2013, 00:05     Удаление элемента из середины списка
Ответ Создать тему
Опции темы

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