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

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

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

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

27.10.2013, 21:20. Просмотров 1707. Ответов 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, пытался по-разному её менять, но ни к чему хорошему это не привело. Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.10.2013, 21:20
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Удаление элемента из середины списка (C++):

Удаление элемента из середины массива(статического) - C++
Хотелось бы узнать как удалить элемент из середины массива(не динамического, не вектора). Не могли бы вы написать простенькую программу для...

Реализация списка.Удаление хвостового элемента.Поиск элемента - C++
Всем привет,мое задание выглядит так : В класс List&lt;T&gt; из классной работы добавить следующие методы: void addHead(T...

Удаление элемента списка и всего списка - C++
Компилируется, но не работает. Что и как исправить? #include &lt;cstdlib&gt; #include &lt;iostream&gt; #include &lt;cstring&gt; #define M 5 ...

Удаление элемента из списка и поиск элемента - C++
Нужно удалить определенный элемент из списка. Найти элемент в списк и вывести на него всю информацию. Вот код. Не знаю как написать...

Удаление элемента со списка - C++
Вот у меня есть код: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; struct OS { char Name ; ...

Удаление элемента из списка - C++
Здравствуйте, нужна помощь, программа, выполняющая следующие задания на основе двусвязного списка. Не удается удалить элемент по дате...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
XRuZzz
Антикодер
671 / 572 / 28
Регистрация: 15.09.2012
Сообщений: 2,519
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
Антикодер
671 / 572 / 28
Регистрация: 15.09.2012
Сообщений: 2,519
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
Антикодер
671 / 572 / 28
Регистрация: 15.09.2012
Сообщений: 2,519
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
Антикодер
671 / 572 / 28
Регистрация: 15.09.2012
Сообщений: 2,519
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
Антикодер
671 / 572 / 28
Регистрация: 15.09.2012
Сообщений: 2,519
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
Да, я знаю. Я все время пробовал без "*".
XRuZzz
Антикодер
671 / 572 / 28
Регистрация: 15.09.2012
Сообщений: 2,519
28.10.2013, 00:05 #13
но даже если вы исправите, то функция будет называться не DelElem, а скорее deleteNext()

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

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

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

помоему больше нет вариантов
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.10.2013, 00:05
Привет! Вот еще темы с ответами:

Удаление элемента из списка - C++
необходимо удалить первый элемент из списка, помогите пожалуйста переписать функцию и помогите с вызовом этой функции в main() ...

Удаление элемента из списка - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; struct FileStruct //Структура файла { ...

Удаление элемента из списка - C++
Нужно удалить из списка элемент, стоящий после элемента на который указывает Р. Очень срочно надо! Заранее спасибо.

Удаление элемента из списка - C++
Нужно удалить всех студентов с оценками 2. Entry *begin = new Entry; int mark=2; Entry *current=begin; while(current){ ...


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

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

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