Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.05.2023, 15:39   #1
lenaiv
Пользователь
 
Регистрация: 16.03.2023
Сообщений: 67
По умолчанию не работает функция Max и Min в двусвязном списке

У меня программа работы со списками. Добавляет, печатает, находит Max, а Min пишет 0 и не меняет. Может кто-то поможет мне исправить. Похожую делала в односвязном, работает, а в двусвязном нет.
То есть не работает следующая функция: Поменять местами элементы, которые стоят перед Min и после Max, если хотя бы один из них не является крайним, то просто поменять местами Max и Min.
Подскажите, как можно исправить работу функции Max и Min.
Код:
#include <iostream>
#include <Windows.h> 
 
using namespace std;
 
 
struct node
{
    int elem; 
    node* next; 
    node* prev; 
};
 
struct lists 
{
private: 
    node* end; 
    int quanity; 
public: 
    node* head; 
    lists() 
    {
        head = end = new node();
        quanity = 0;
    }
 
    int count() 
    {
        return quanity;
    }
 
    node* find(int el)
    {
        node* curr = head->next; 
        while (curr != nullptr)  
        {
            if (curr->elem == el)
            {
                return curr;
            }
            curr = curr->next;
        }
        return nullptr;
    }
    node* find(int el, node*& aft)
    {
        node* curr = head->next;
        aft = head;
        while (curr != nullptr)
        {
            if (curr->elem == el)
            {
                return curr;
            }
            aft = curr;
            curr = curr->next;
        }
        return nullptr;
    }
 
    void push_back(int el)
    {
        node* curr = new node();
        curr->elem = el;
        end->next = curr;
        end = curr;
        quanity++;
    }
 
    void push_forward(int el)
    {
        node* curr = new node();
        curr->elem = el;
        curr->next = head->next;
        head->next = curr;
        if (end == head)
        {
            end = curr;
        }
        quanity++;
    }
 
 
    void print() const
    {
        if (head->next == nullptr)
        {
            cout << "Список пуст" << endl;
            return;
        }
        node* current = head->next;
        while (current != nullptr)
        {
            cout << current->elem << " ";
            current = current->next;
        }
        cout << endl;
    }
 
    void clear()
    {
        node* current = head->next;
        while (current != nullptr)
        {
            node* next = current->next;
            delete current;
            current = next;
        }
        head->next = nullptr;
        end->next = nullptr;
        end = head;
        quanity = 0;
        cout << "Список очищен" << endl;
    }
};
// Функция для поиска Min и Max элементов в двусвязном списке
void findMinMax(node* head, int& min, int& max)
{
    node* current = head;
    min = head->elem;
    max = head->elem;
 
    while (current != nullptr)
    {
        if (current->elem < min)
        {
            min = current->elem;
        }
        if (current->elem > max)
        {
            max = current->elem;
        }
        current = current->next;
    }
    cout << "Min = " << min << endl;
    cout << "Max = " << max << endl;
}
// Функция для обмена значениями двух элементов в двусвязном списке
void swapValues(node* el1, node* el2)
{
    int temp = el1->elem;
    el1->elem = el2->elem;
    el2->elem = temp;
}
 
// Функция для обмена элементами перед Min и после Max элементов двусвязного списка
void swapElementList_2(node* head)
{
    if (head == nullptr)
    {
        return;
    }
    node* current = head;
    node* prevMin = nullptr;
    node* minNode = nullptr;
    node* maxNode = nullptr;
    int min, max;
 
    cout << "head->elem" << head->elem << endl;
    findMinMax(head, min, max);
    while (current != nullptr)
    {
        if (current->elem <= min)
        {
            minNode = current;
        }
        if (current->elem >= max)
        {
            maxNode = current;
        }
        if (current->prev != nullptr && current->prev->elem == min)
        {
            prevMin = current->prev;
        }
 
        current = current->next;
    }
 
    bool isMinEdge = (minNode == head || minNode->next == nullptr);
    bool isMaxEdge = (maxNode == head || maxNode->next == nullptr);
    // Обменивакм значениями элементы перед Min и после Max
    if (isMinEdge && isMaxEdge)
    {
        // Если и Min, и Max элементы крайние, просто меняем их местами
        swapValues(minNode, maxNode);
    }
    else if (isMinEdge)
    {
        // Если только Min элемент крайний, меняем местами его и следующий за Max
        swapValues(minNode, maxNode->next);
    }
    else if (isMaxEdge)
    {
        // Если только Max элемент крайний, меняем местами предыдущий Min и Max элементы
        swapValues(prevMin, maxNode);
    }
    else
    {
        // Если ни Min, ни Max элементы не являются крайними, меняем местами элемент перед Min и элемент после Max
        swapValues(prevMin, maxNode->next);
    }
}
 
void printList_2(node* head)
{
    node* current = head;
    while (current != nullptr)
    {
        cout << current->elem << " ";
        current = current->next;
    }
    cout << endl;
}
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    lists myList;
    int el, el2;
    int c;
    int choice;
    int ch;
    while (true)
    {
        cout << "Введите команду" << endl;
        cout << "1 - работа с двусвязным списком " << endl;
        cout << "2 - выйти" << endl;
        cin >> ch;
        if (ch == 2)
        {
            exit(0);
            break;
        }
        if (ch == 1)
        {
            while (true)
            {
                cout << "Выберите цифру меню: " << endl;
                cout << "1 - добавить элемент в конец" << endl;//
                cout << "2 - добавить элемент в начало" << endl;
                cout << "3 - показать список" << endl;
                cout << "4 - очистить список" << endl;
                cout << "5 - Функция Min_Max" << endl;
                cout << "6 - назад" << endl;
                cin >> c;
                if (c == 6)
                {
                    break;
                }
                switch (c)
                {
                case 1:
                    cout << "Введите элемент: ";
                    cin >> el;
                    myList.push_back(el);
                    cout << "Элемент добавлен в конец списка" << endl;
                    break;
                case 2:
                    cout << "Введите элемент: ";
                    cin >> el;
                    myList.push_forward(el);
                    cout << "Элемент добавлен в начало списка" << endl;
                    break;
                case 3:
                    myList.print();
                    break;
                case 4:
                {
                    myList.clear();
                    break;
                }
                case 5:
                {
                    cout << "Двусвязный список до изменения: ";
                    myList.print();
                    cout << "myList.head->elem: " << myList.head->elem << endl;
                    swapElementList_2(myList.head);
                    cout << "Двусвязный список после изменения: ";
                    myList.print();
                    break;
                }
                case 6:
                    break;
                default://Если введено число не соответствующее номеру (case), то выдает ошибку 
                    cout << "Некорректный ввод. Попробуйте еще раз." << endl;
                    break;
                }
            }
        }
    }
    return 0;
}
вот что выходит
Изображения
Тип файла: png 0000000000000000000000000.PNG (11.4 Кб, 19 просмотров)

Последний раз редактировалось lenaiv; 17.05.2023 в 15:54.
lenaiv вне форума Ответить с цитированием
Старый 17.05.2023, 16:00   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

В функции clear не нужно делать "end->next = nullptr;", т.к. элемент end будет уже удален. Вы добавили поле prev, но не заполняете его при добавлении элемента в список, поэтому значение поля нельзя использовать в других функциях. В head->elem не хранится значение какого-либо элемента, так что не нужно его использовать.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 17.05.2023, 16:20   #3
lenaiv
Пользователь
 
Регистрация: 16.03.2023
Сообщений: 67
По умолчанию

так очистка clear у меня работает без ошибок. У меня минимум всегда 0 и не меняет элементы
lenaiv вне форума Ответить с цитированием
Старый 17.05.2023, 17:38   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от lenaiv Посмотреть сообщение
работает без ошибок
Если программа сразу не падает, это не значит, что ошибок нет.
Цитата:
Сообщение от lenaiv Посмотреть сообщение
минимум всегда 0
Потому что не надо инициализировать минимум и максимум элементом из head, который не был введен пользователем.
Вроде работает, хотя думаю, что требуется не сами значения в элементах списка поменять, а аккуратно перевесить все указатели:
Код:
#include <iostream>
#include <Windows.h>

using namespace std;

struct node
{
    int elem;
    node* next;
    node* prev;
};

void swapValues(node* el1, node* el2)
{
    int temp = el1->elem;
    el1->elem = el2->elem;
    el2->elem = temp;
}

struct lists
{
private:
    node* end;
    int quanity;
public:
    node* head;
    lists()
    {
        head = end = new node();
        quanity = 0;
    }

    int count()
    {
        return quanity;
    }

    void push_back(int el)
    {
        node* curr = new node();
        curr->elem = el;
        end->next = curr;
        curr->prev = end;
        end = curr;
        quanity++;
    }

    void push_forward(int el)
    {
        node* curr = new node();
        curr->elem = el;
        curr->next = head->next;
        head->next = curr;
        curr->prev = head;
        if (end == head)
        {
            end = curr;
        }
        quanity++;
    }

    void print() const
    {
        if (head->next == nullptr)
        {
            cout << "Список пуст" << endl;
            return;
        }
        node* current = head->next;
        while (current != nullptr)
        {
            cout << current->elem << " ";
            current = current->next;
        }
        cout << endl;
    }

    void clear()
    {
        node* current = head->next;
        while (current != nullptr)
        {
            node* next = current->next;
            delete current;
            current = next;
        }
        head->next = nullptr;
        end = head;
        quanity = 0;
        cout << "Список очищен" << endl;
    }

    void swapElements()
    {
        if (head->next == nullptr)
        {
            cout << "Список пуст" << endl;
            return;
        }

        node* current = head->next;
        node* min = current, * max = current;

        while (current != nullptr)
        {
            if (current->elem < min->elem)
            {
                min = current;
            }
            else if (current->elem > max->elem)
            {
                max = current;
            }
            current = current->next;
        }
        cout << "Min = " << min->elem << endl;
        cout << "Max = " << max->elem << endl;

        node* prevMin = min, * postMax = max;
        if (prevMin->prev != head)
        {
            prevMin = prevMin->prev;
        }
        if (postMax->next != nullptr)
        {
            postMax = postMax->next;
        }
        if (prevMin != postMax)
        {
            swapValues(prevMin, postMax);
        }
    }
};

int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    lists myList;
    int el;
    int c;
    int ch;
    while (true)
    {
        cout << "Введите команду" << endl;
        cout << "1 - работа с двусвязным списком " << endl;
        cout << "2 - выйти" << endl;
        cin >> ch;
        if (ch == 2)
        {
            exit(0);
            break;
        }
        if (ch == 1)
        {
            while (true)
            {
                cout << "Выберите цифру меню: " << endl;
                cout << "1 - добавить элемент в конец" << endl;//
                cout << "2 - добавить элемент в начало" << endl;
                cout << "3 - показать список" << endl;
                cout << "4 - очистить список" << endl;
                cout << "5 - Функция Min_Max" << endl;
                cout << "6 - назад" << endl;
                cin >> c;
                if (c == 6)
                {
                    break;
                }
                switch (c)
                {
                case 1:
                    cout << "Введите элемент: ";
                    cin >> el;
                    myList.push_back(el);
                    cout << "Элемент добавлен в конец списка" << endl;
                    break;
                case 2:
                    cout << "Введите элемент: ";
                    cin >> el;
                    myList.push_forward(el);
                    cout << "Элемент добавлен в начало списка" << endl;
                    break;
                case 3:
                    myList.print();
                    break;
                case 4:
                {
                    myList.clear();
                    break;
                }
                case 5:
                {
                    cout << "Двусвязный список до изменения: ";
                    myList.print();
                    myList.swapElements();
                    cout << "Двусвязный список после изменения: ";
                    myList.print();
                    break;
                }
                case 6:
                    break;
                default://Если введено число не соответствующее номеру (case), то выдает ошибку
                    cout << "Некорректный ввод. Попробуйте еще раз." << endl;
                    break;
                }
            }
        }
    }
    return 0;
}
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 17.05.2023 в 17:41.
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сортировка в двусвязном списке Daninil Общие вопросы C/C++ 0 09.02.2020 17:39
Segfault в двусвязном списке в си Глеб Давыдов Помощь студентам 4 03.03.2016 23:06
помогите исправить процедуру Del,в двусвязном списке svetik290895 Общие вопросы C/C++ 0 10.05.2015 19:32
Удаление элемента в двусвязном списке (Delphi). tgig Помощь студентам 4 10.10.2013 10:36
Сортировка char в двусвязном списке preanik Помощь студентам 0 12.05.2013 02:18