C++ для начинающих. Удаление элемента из двусвязного списка

Продолжаем знакомиться с двусвязным списком. Чтобы не загромождать статью ознакомления с созданием двусвязного списка, я сделал этот материал как отдельный, но это всё из одной и той же темы. Смотрим и учимся удалять элемент из двусвязного списка.
Функция удаления немного сложна для понимания, потому как в зависимости от позиции элемента может код пишется немного по-разному.

    Посмотрим на возможные варианты

  • Список пустой (Чего удалять, если ничего нет?)
  • Указанный номер элемента превышает количество элементов в списке.
  • В списке всего один элемент.
  • В списке несколько элементов и удаляется первый.
  • Удаляется последний элемент списка.
Вот для каждого случая приходится писать маленький кусочек кода. Из-за этого функция удаления элемента из двусвязного списка получается не самой маленькой.
Чтобы немного упростить задачу, нужно ввести переменную-счётчик, считающую число элементов в списке. (Так кода будет поменьше).
Итак, считаю, что с созданием списка вы уже знакомы и способны писать его даже с закрытыми глазами. Поэтому сосредотачиваю ваше внимание непосредственно на функции удаления элемента из двусвязного списка.

Можно по другому делать, но принцип везде будет один и тот же. Я предпочёл в зависимости от ситуации выполнять код и сразу выходить из функции удаления (а зачем проверять то, что уже не нужно?). Главное, не забывать, что если есть счётчик элементов (а он у меня тут есть), то при добавлении его надо увеличивать, при удалении уменьшать.
Я сознательно не пишу код, обозначая вероятные ошибки (например, если номер удаляемого элемента больше чем вообще чисел в списке). Так можно сосредоточить внимание на нужном. Но, обязательно допишите этот кусочек сами. Это очень важно. (имеется в виду кусочек, исключающий некорректный ввод данных для удаления).
Схематично картинка, демонстрируемая ниже, получилась не слишком наглядной, но, может, внесет ясности.
Схема удаления элемента из списка
Узел можно удалить только тогда, когда не нарушится связь с другими элементами.
Надеюсь, этот материал чему-то вам помог и смог чему-то вас научить.

7 комментариев на «“C++ для начинающих. Удаление элемента из двусвязного списка”»

  1. Иван:

  2. Иван:

    Какое-же гигантское, человеческое спасибо Вам! Как же вы помогли всё это понять…вот теперь задачи нарешиваю:)

  3. Артем:

    А почему в цикле for при удалении элемента где-то в середине списка мы адрес указываем х-1? ведь х это значение переменной.

    • Это не адрес указывается. Это указывается число, которое обозначает количество необходимых итераций. Пока i не станет равным (x-1), цикл for будет работать.
      x — это то число, которое отдаётся вовнутрь функции.

  4. мне нужно помочь

  5. #include»stdafx.h»
    #include <cstring>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    struct botanik
    {
    char FIO[20];
    double cena;
    char gorod[20];
    double summ = 0;
    //указатели на следующую и предыдущую структуры
    struct botanik *p1, *p2;
    };
    /*Указатели на первую, текущую, предыдущую, рабочую,последнюю структуры*/
    struct botanik *first, *tek, *pred, *rab, *last;
    void enter_botanik()
    {
    //Ввод новой структуры в список
    cout << «Введите ФИО : «;
    cin >> tek->FIO;
    cout << «Введите цену изобретения : «;
    cin >> tek->cena;
    cout << «Введите город : «;
    cin >> tek->gorod;
    }
    //новый ботаник
    void new_botanik()
    {
    if (!first) //список пуст
    {
    tek = new botanik;

    if (!tek)
    {
    cout << «Недостаточно памяти» << endl;
    exit(1);
    }
    enter_botanik();
    first = tek;
    pred = tek;
    last = tek;
    //следующей и предыдущей структур нет
    tek->p1 = nullptr;
    tek->p2 = nullptr;
    }
    else
    //структура не первая
    {
    pred = tek;
    tek = new botanik;
    // утечка памяти!
    if (!tek)
    {
    cout << «Недостаточно памяти» << endl;
    exit(1);
    }
    enter_botanik();
    pred->p1 = tek;
    //установка указателя предыдущей структуры
    tek->p2 = pred;
    tek->p1 = nullptr; //следующей структуры нет
    last = tek;
    }
    }
    // вывод всех структур от начала к концу
    void output1()
    {
    tek = first;
    for (tek; tek; tek = tek->p1) //переход к следующей структуре
    {
    cout << tek->FIO << » » << tek->cena << » » << tek->gorod << » » << endl;
    }
    cin.get(); //ожидание нажатия клавиши
    }
    // вывод всех структур от конца к началу
    void output2()
    {
    for (tek = last; tek; tek = tek->p2) //переход к предыдущей структуре
    {
    cout << tek->FIO << » » << tek->cena << » » << tek->gorod << » » << endl;
    }
    cin.get(); //ожидание нажатия клавиши
    }
    void sum()
    {
    double s = 0; //сумма окладов
    for (tek = last; tek; tek = tek->p2)//переход к следующей структуре
    {
    s =s+ tek->cena;
    }
    cout << «Сумма изобретений = » << s << endl;
    cin.get();
    return;
    }
    int main()
    {
    setlocale(LC_ALL, «Russian»);
    //Ввод 3 структур
    first = nullptr;
    for (int i = 1; i <= 3; i++)
    new_botanik();
    //печать всех структур
    cout << «\nВведенные структуры» << endl;
    output1();
    cout << endl;
    output2();
    cout << endl;
    sum(); //вычисление и вывод сумму изобретений
    //вывод оставшихся структур
    //удаление второй структуры
    rab = first->p1;
    first->p1 = rab->p1;
    delete(rab);
    cout << «После удаления второй структуры» << endl;
    output1();
    cout << endl;
    return 0;
    }

    здесь 2 структуры удаления мне нужно 1 структуры

  6. игорь:

    temp2 не нужен, можно сразу temp->Prev->Next = temp->Next; temp->Next->Prev = temp->Prev

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Поиск

 
     

Случайная книга в электронном формате

https://www.litres.ru/denis-kolisnichenko/programmirovanie-dlya-android-samouchitel/?lfrom=15589587
Яндекс.Метрика