Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.98/40: Рейтинг темы: голосов - 40, средняя оценка - 4.98
82 / 78 / 34
Регистрация: 13.02.2018
Сообщений: 1,347

Добавления в односвязный список

24.08.2018, 22:04. Показов 8589. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток, проходил я тут помеж тем С++, и увидел тему про список, в котором я давно хотел разобраться, а точнее о работе указателей, хотел попробовать просто добавить к уже готовому коду метод вставки, но как оказалось, я этого не могу сделать, скажите что не так с функцией?
C++
1
2
3
4
5
6
7
void add(list *head)
{
        list *p = new list();
        cin >> p->inf;
        p->next = head;
        head = p;
}
Весь код
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <fstream>
 
using namespace std;
 
struct list
{
    int inf;
    list *next;
};
 
void create(list *&head, int n)
{
    list *p = head;
    head = 0;
    for (int i = 1; i <= n; i++)
    {
        p = new list;
        cin >> p->inf;
        p->next = head;
        head = p;
    }
}
 
void add(list *head)
{
        list *p = new list();
        cin >> p->inf;
        p->next = head;
        head = p;
}
 
void print(list*head)
{
    list *p = head;
    while (p != NULL)
    {
        cout << p->inf << "->";
        p = p->next;
    }
    cout << "NULL\n" ;
    return;
}
 
int main()
{
    setlocale(LC_ALL, "Russian");
    list *head;
    
    int n;
    cin >> n;
    create(head, n);
    add(head);
    print(head);
    
    system("pause");
    return 0;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.08.2018, 22:04
Ответы с готовыми решениями:

Ошибка добавления в односвязный список
Здравствуйте! Срочно помогите исправить ошибку в программе. Задача: Из бинарного дерево все отрицательные элементы добавить в односвязный...

Односвязный список: функция добавления записи не работает
Вообщем написал функцию для добавления записи в конец, все работает без ошибок, но когда просматриваю список функцией для просмотра, пишет,...

Функция добавления элемента в односвязный список в указанную позицию
Здравствуйте! Помогите пожалуйста написать функцию добавления элемента в односвязный список в указанную позицию.Не могу сообразить как...

22
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
24.08.2018, 22:12
Цитата Сообщение от k0vpack Посмотреть сообщение
p->next = head;
head = p;
вот что ты здесь делаешь?
нужно указатель переписать
примерно так
C++
1
2
p->next = head->next;
head->next= p;
0
82 / 78 / 34
Регистрация: 13.02.2018
Сообщений: 1,347
24.08.2018, 22:17  [ТС]
ValeryS, как по мне, то
C++
1
p->next = head;
текущий элемент -> следующий = последний элемент (то есть не считая только что созданный)
то есть указатель из текущего элемента (который добавляем)будет равен предыдущему началу списка
C++
1
head = p;
следующий = текущему
и это будет указывать на начало списка, при последующим добавлении этот head будет возвращать последний элемент
0
Заблокирован
24.08.2018, 22:22
C++
1
2
3
4
5
6
7
8
9
10
11
12
void add(list* &head)
{
        list* p=head;
        if(!p) head=p=new list();
        else
        {
            while(p->next) p=p->next;
            p=p->next=new list();
        }
        p->next=0;
        cin>>p->inf;
    }//вроде этого
........
list *head=0;
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
24.08.2018, 22:24
Цитата Сообщение от k0vpack Посмотреть сообщение
head = p;
вот здесь ты просто потерял память
Цитата Сообщение от k0vpack Посмотреть сообщение
как по мне,
а теперь давай на пальцах
head заголовок, дословно голова
он один и не меняется
или он указывает на NULL это значит список пуст
или на какой то элемент
примерно так
head->next =p1
p1->next =p2
p2->next =p3
p3->next =p4
p4->next =NULL
0
82 / 78 / 34
Регистрация: 13.02.2018
Сообщений: 1,347
24.08.2018, 22:28  [ТС]
Цитата Сообщение от Biger18 Посмотреть сообщение
while(p->next) p=p->next;
но head изначально равен последнему добавленому элементу, смысл с проверок?
ValeryS, получается если использовать ваши изменения то я добавлю не в конец (или начало) как предпологается, а после между итак последний элементом и предпоследним, то есть если было 1 2 4 2, а я вставлю 3, то будет 1 3 2 4 2, вместо 3 1 2 4 2.
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
24.08.2018, 22:34
Цитата Сообщение от k0vpack Посмотреть сообщение
но head изначально равен последнему добавленому элементу
еще раз повторю head -голова, указывает на начала списка
0
82 / 78 / 34
Регистрация: 13.02.2018
Сообщений: 1,347
24.08.2018, 22:37  [ТС]
ValeryS, для кого начало, для кого конец, я где-то впервые прочитал о списке, что NULL это начало, и так пришлось, теперь путаюсь, но равен то он последнему добавленому элементу который и есть начало, выходит нужно ссылаться на него
C#
1
p->next = head;
а не на того на кого ссылается он, как у вас
C#
1
p->next = head->next;
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
24.08.2018, 22:39
Цитата Сообщение от k0vpack Посмотреть сообщение
то есть если было 1 2 4 2
не может такого быть, у списка не может быть элементов с одним индексом
Цитата Сообщение от k0vpack Посмотреть сообщение
а я вставлю 3, то будет 1 3 2 4 2
куда нужно туда и вставишь
поэтому
Цитата Сообщение от k0vpack Посмотреть сообщение
void add(list *head)
неправильное имя аргумента
правильней написать так
C++
1
void add(list *prev)
prev предыдущий

Добавлено через 1 минуту
Цитата Сообщение от k0vpack Посмотреть сообщение
я где-то впервые прочитал о списке, что NULL это начало,
хотелось бы почитать
0
82 / 78 / 34
Регистрация: 13.02.2018
Сообщений: 1,347
24.08.2018, 22:42  [ТС]
ValeryS,
1->3->2->4->2->NULL
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
25.08.2018, 00:08
Лучший ответ Сообщение было отмечено k0vpack как решение

Решение

k0vpack, Вы все правильно делаете, за исключением одного. Стоит различать передачу аргумента функции по значению и по ссылке.

При передаче аргумента по значению создается его локальная копия, которую можно изменять, но эти изменения никак не отразятся на первоначальной переменной. Пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ...
void set_value(int x, int new_value)
{
    // Изменяется локальная копия переменной.
    x = new_value;
}
 
int main()
{
    int x = 5;
    set_value(x, 10);
 
    cout << x; // x по прежнему равен 5.
 
    return 0;
}
В линейном односвязном списке переменная list *head указывает на первый элемент списка. При добавлении нового элемента в начало соответственно первым станет другой элемент и значение head должно поменяться. Как и в примере выше, функция set_value должна изменить значение переменной. В таком случае необходимо не создавать локальную копию переменной, а работать с переменной напрямую. Для этого необходимо передать аргумент функции по ссылке. Это делается добавлением знака & перед именем аргумента в описании функции:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void set_value(int &x, int new_value)
{
    // Изменяется значение переменной, переданной по ссылке.
    x = new_value;
}
 
int main()
{
    int x = 5;
    set_value(x, 10);
 
    cout << x; // Теперь x равен 10.
 
    return 0;
}
Исправим вашу функцию:

C++
1
2
3
4
5
6
7
void add(list *&head)
{
        list *p = new list; // Скобки () тут кстати не обязательны.
        cin >> p->inf;
        p->next = head;
        head = p;
}
Теперь все должно работать так, как задумано.
1
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
25.08.2018, 07:44
k0vpack, valen10, расскажите мне, как вы будете обращаться к списку если у вас постоянно меняется первый элемент? как найти начало?
0
 Аватар для Human_foot
156 / 114 / 36
Регистрация: 27.06.2018
Сообщений: 257
25.08.2018, 09:49
Цитата Сообщение от valen10 Посмотреть сообщение
Вы все правильно делаете, за исключением одного. Стоит различать передачу аргумента функции по значению и по ссылке.
Совершенно верно



Цитата Сообщение от ValeryS Посмотреть сообщение
еще раз повторю head -голова, указывает на начала списка
Цитата Сообщение от ValeryS Посмотреть сообщение
расскажите мне, как вы будете обращаться к списку если у вас постоянно меняется первый элемент? как найти начало?
Нет, всё зависит от подхода FIFO или FILO. У автора FILO, а вы заставляете его использовать FIFO
0
Заблокирован
25.08.2018, 09:55
FILO стеком называется, а не списком
0
 Аватар для Human_foot
156 / 114 / 36
Регистрация: 27.06.2018
Сообщений: 257
25.08.2018, 10:05
А FIFO - очередь
А для списков присуще любое направление, и даже двунаправленность.
0
82 / 78 / 34
Регистрация: 13.02.2018
Сообщений: 1,347
25.08.2018, 10:07  [ТС]
ValeryS, так *head всегда и будет указывать на первый элемент
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,870
25.08.2018, 11:18
Цитата Сообщение от k0vpack Посмотреть сообщение
так *head всегда и будет указывать на первый элемент
где?
давай по строкам
C++
1
2
3
4
5
6
7
void add(list *head) // head это элемент списка после которого нужно вставить
{
        list *p = new list();// выделили память под новый элемент
        cin >> p->inf; 
        p->next = head;  //новый элемент указывает на head, нужно наоборот
        head = p;         // здесь непонятно что хотел, но память на которую ссылается head  потеряна, элемент ссылается на самого себя
}
0
82 / 78 / 34
Регистрация: 13.02.2018
Сообщений: 1,347
25.08.2018, 11:28  [ТС]
ValeryS,
Цитата Сообщение от ValeryS Посмотреть сообщение
давай по строкам
изначально при создании списка head == NULL, то есть список пуст, но после его создания (допустим функцией create которая была в моем коде)
C++
1
2
3
4
5
6
7
8
9
10
11
void create(list *&head, int n) // указатель на начало списка т.е. сам список, n = кол-во элементов при создании
{
    list *p = head; // указательно на начало, в нашем случае на null, p.s. зачем эта строка я так и не понял, функцию позаимствовал, но хотел сделать функцию добавления
    for (int i = 0; i < n; i++)// цикл простой
    {
        p = new list;//выделяем память
        cin >> p->inf;//запись переменной
        p->next = head;// теперь созданый нами элемент будет указывать на начало списка где лежит предыдущий добавленый элемент, либо если элементов нет то на NULL
        head = p;// тут начало списка присваивается в верхний добавленый элемент т.е. последний, выходит эта переменная типа list после выхода из функции изменится и будет указывать на начало списка, т.е. держать в себе указатель на начало, и при последующей передачи этого аргумента в другие функции эта переменная будет указывать на начало списка
    }
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
void add(list *&head) // [U]head это элемент списка после которого нужно вставить[/U]
{                                    // неверно, head это элемент который указывает на начало, и перед ним нужно вставить, так как
                                      // у списка LIFO элемент который добавляем становиться первым
        list *p = new list();// выделили память под новый элемент
        cin >> p->inf; 
        p->next = head;  //[U]новый элемент указывает на head, нужно наоборот[/U]
                                  //новые элемент указывает что следующим за ним идет последний созданный до этого, т.е. 
                                  //ранее созданный элемент был первым, то теперь наш теперь созданный будет первый, где тот
                                 // ранее созданный станет вторым
        head = p;         // [U]здесь непонятно что хотел, но память на которую ссылается head  потеряна, элемент ссылается на самого себя[/U]
                               // тут переменная head будет указывать на новое начало списка
}
0
 Аватар для Human_foot
156 / 114 / 36
Регистрация: 27.06.2018
Сообщений: 257
25.08.2018, 11:31
Цитата Сообщение от ValeryS Посмотреть сообщение
p->next = head; *//новый элемент указывает на head, нужно наоборот
head = p; // здесь непонятно что хотел, но память на которую ссылается head потеряна, элемент ссылается на самого себя
}
Тут новый элемент становится головой, а p->next указывает на старую голову.
0
26 / 23 / 12
Регистрация: 25.06.2018
Сообщений: 91
25.08.2018, 11:52
Задача добавления в начало или конец списка - немного разные задачи. Если нет указания, как хранить список после ввода, то легче менять head и вставлять в начало и список получается инвертированным, как стек LIFO. Если требуется FIFO, то тогда алгоритм добавления должен быть другой: поиск последнего элемента, у которого next равен NULL и прописывание в эту ячейку адреса нового элемента. При этом лучше, когда функция add возращает адрес этого последнего элемента и ей передается адрес поледнего элемента. Если вхолдящий параметр адрес последнего элемента равен NULL, то будет создан первый элемент.
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
struct list
{
    int inf;
    list *next;
         list()
           : next(NULL)
         {
         }
};
list* add(list* head = NULL)
{
    list *p = new list;
    cin >> p->inf;
    if(head != NULL)
       head->next = p;
    return p;
}
// поменяется функция create, которая возвратит голову.
list* create(int n)
{
    list* head = NULL;
    if(i > 0)
   {
      head = add();
      list* tmp = head;
      for (int i = 2; i <= n; i++)
          tmp = add(tmp);
    }
    return head;
}
 
void print(list* head)
{
    while (head != NULL)
    {
        cout << head->inf << "->";
        head = head->next;
    }
    cout << "NULL\n" ;
    return;
}
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    int n;
    cin >> n;
 
    int n;
    cin >> n;
    
    list* head = create(n);
 
    print(head);
    
    system("pause");
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.08.2018, 11:52
Помогаю со студенческими работами здесь

Сформировать список из 10 книг, используя динамическую структуру данных односвязный список
друзья спасайте Сформировать список из 10 книг, используя динамическую структуру данных односвязный список С++

Создать класс «Квартира», в котором список комнат реализовать как односвязный список
Добрый день,написал фот такой клас по заданию:Создать класс «Квартира», в котором список комнат реализовать как односвязный список....

Односвязный список: заносить в новый список элементы исходного, которые больше заданного значения
Можете пожалуйста помочь в решении проблемы не. Не могу создать функцию которая будет с созданного заранее списка заносить в новый элементы...

Составить односвязный список на основе класса, объекты которого будут формировать этот список
Составить односвязный список на основе класса, объекты которого будут формировать этот список. В описание класса должны входить данные...

Заменить массив структур на односвязный список, и на двусвязный список
Взять текст задания и заменить массив структур на односвязный список, и на двусвязный список using namespace std; class person { ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru