Wstaw przed najmłodszą

0

Cześć,

Potrzebuję pomocy z moim kodem C++
Czy ktoś może mnie nakierować jak powinienem rozwiązać ten problem?
Coś tam udało mi się napisać, ale mam problem z punktem 5
Problem najlepiej widać po uruchomieniu kodu 😁

  1. Wczytać z klawiatury n (n – wczytana przez użytkownika) kolejnych danych o roślinach (wiek,
    gatunek, cena) i utworzyć z nich listę jednokierunkową w kolejności zgodnej z wczytywaniem.
  2. Wydrukować utworzoną listę, korzystając z funkcji drukującej listę zaczynającą się pod jakimś
    adresem.
  3. Usunąć z listy zaczynającej się pod jakimś adresem co drugą roślinę na liście, której wiek jest
    większy od poprzedniej rośliny na liście, po czym wyświetlić liczbę usuniętych elementów.
  4. Ponownie wydrukować listę.
  5. Wstawić przed najmłodszą rośliną nową roślinę o danych wczytanych przez użytkownika.
  6. Ponownie wydrukować listę.
  7. Skasować utworzoną listę korzystając z funkcji kasującej listę zaczynającą się pod jakimś
    adresem.
    Uwaga 1: Słowo "jakiś" oznacza parametr funkcji.
    Uwaga 2: Wykonując różne działania na liście (pkt 2-7) należy założyć, że nie znamy ilości elementów
    listy, więc trzeba uważać, aby nie odwoływać się do pola next elementu, który nie istnieje (czyli ma
    adres NULL); w szczególności należy sprawdzać, czy lista nie jest pusta (adres głowy ==NULL) i czy ma
    ona dosyć elementów (aby nie wykonywać operacji niemożliwych do wykonania)

A oto kod C++

#include <iostream>
#include <string>

using namespace std;

// Definicja struktury Roślina dla przechowywania danych o roślinach
struct Roslina {
    int wiek;
    string gatunek;
    float cena;
    Roslina *nastepna;
};

// Funkcja do dodawania nowej rośliny na koniec listy
void dodajRosline(Roslina *&glowa, int wiek, string gatunek, float cena) {
    Roslina *nowaRoslina = new Roslina{wiek, gatunek, cena, nullptr};
    
    if (glowa == nullptr) {
        glowa = nowaRoslina;
    } else {
        Roslina *aktualna = glowa;
        while (aktualna->nastepna != nullptr) {
            aktualna = aktualna->nastepna;
        }
        aktualna->nastepna = nowaRoslina;
    }
}

// Funkcja do wydrukowania listy
void drukujListe(Roslina *glowa) {
    Roslina *aktualna = glowa;
    while (aktualna != nullptr) {
        cout << "Wiek: " << aktualna->wiek << ", Gatunek: " << aktualna->gatunek << ", Cena: " << aktualna->cena << endl;
        aktualna = aktualna->nastepna;
    }
}

// Funkcja do usunięcia co drugiej rośliny spełniającej warunek
int usunCoDruga(Roslina *&glowa) {
    if (glowa == nullptr || glowa->nastepna == nullptr) return 0;

    int liczbaUsunietych = 0;
    bool usun = false;
    Roslina *aktualna = glowa;

    while (aktualna != nullptr && aktualna->nastepna != nullptr) {
        if (aktualna->nastepna->wiek > aktualna->wiek) {
            if (usun) {
                Roslina *doUsuniecia = aktualna->nastepna;
                aktualna->nastepna = doUsuniecia->nastepna;
                delete doUsuniecia;
                liczbaUsunietych++;
                usun = false;
            } else {
                usun = true;
            }
        }
        aktualna = aktualna->nastepna;
    }

    return liczbaUsunietych;
}

// Funkcja do wstawienia nowej rośliny przed najmłodszą
void wstawPrzedNajmlodsza(Roslina *&glowa, int wiek, string gatunek, float cena) {
    Roslina *nowaRoslina = new Roslina{wiek, gatunek, cena, nullptr};

    if (glowa == nullptr || glowa->wiek >= wiek) {
        nowaRoslina->nastepna = glowa;
        glowa = nowaRoslina;
    } else {
        Roslina *aktualna = glowa;
        Roslina *poprzednia = nullptr;

        while (aktualna != nullptr && aktualna->wiek < wiek) {
            poprzednia = aktualna;
            aktualna = aktualna->nastepna;
        }

        if (poprzednia == nullptr) {
            nowaRoslina->nastepna = glowa;
            glowa = nowaRoslina;
        } else {
            nowaRoslina->nastepna = aktualna;
            poprzednia->nastepna = nowaRoslina;
        }
    }
}

// Funkcja do skasowania listy
void skasujListe(Roslina *&glowa) {
    while (glowa != nullptr) {
        Roslina *temp = glowa;
        glowa = glowa->nastepna;
        delete temp;
    }
}

int main() {
    Roslina *glowa = nullptr;
    int n, wiek;
    string gatunek;
    float cena;

    cout << "Podaj liczbę roślin: ";
    cin >> n;

    for (int i = 0; i < n; ++i) {
        cout << "Podaj wiek, gatunek i cenę dla rośliny " << i + 1 << ": ";
        cin >> wiek >> gatunek >> cena;
        dodajRosline(glowa, wiek, gatunek, cena);
    }

    cout << "Lista roślin:" << endl;
    drukujListe(glowa);

    int usuniete = usunCoDruga(glowa);
    cout << "Liczba usuniętych roślin: " << usuniete << endl;

    cout << "Lista po usunięciu roślin:" << endl;
    drukujListe(glowa);

    cout << "Podaj wiek, gatunek i cenę dla nowej rośliny: ";
    cin >> wiek >> gatunek >> cena;
    wstawPrzedNajmlodsza(glowa, wiek, gatunek, cena);

    cout << "Lista po dodaniu nowej rośliny:" << endl;
    drukujListe(glowa);

    skasujListe(glowa);

    return 0;
}
0

Problem najlepiej widać po uruchomieniu kodu

Nie bardzo. Pofatygowałem się i uruchomiłem https://wandbox.org/permlink/cgwMLosWdAGebPDn

Wstawić przed najmłodszą rośliną nową roślinę o danych wczytanych przez użytkownika.

U mnie działa. Kodu nie czytam dopóki nie wskażesz konkretnie z czym jest problem.

Lista po usunięciu roślin:
Wiek: 2, Gatunek: tulip, Cena: 10
Wiek: 3, Gatunek: roza, Cena: 15
Podaj wiek, gatunek i cenę dla nowej rośliny: Lista po dodaniu nowej rośliny:
Wiek: 1, Gatunek: kaktus, Cena: 1
Wiek: 2, Gatunek: tulip, Cena: 10
Wiek: 3, Gatunek: roza, Cena: 15
0
several napisał(a):

Problem najlepiej widać po uruchomieniu kodu

Nie bardzo. Pofatygowałem się i uruchomiłem https://wandbox.org/permlink/cgwMLosWdAGebPDn

Wstawić przed najmłodszą rośliną nową roślinę o danych wczytanych przez użytkownika.

U mnie działa. Kodu nie czytam dopóki nie wskażesz konkretnie z czym jest problem.

Lista po usunięciu roślin:
Wiek: 2, Gatunek: tulip, Cena: 10
Wiek: 3, Gatunek: roza, Cena: 15
Podaj wiek, gatunek i cenę dla nowej rośliny: Lista po dodaniu nowej rośliny:
Wiek: 1, Gatunek: kaktus, Cena: 1
Wiek: 2, Gatunek: tulip, Cena: 10
Wiek: 3, Gatunek: roza, Cena: 15

Gdy dodaje nową roślinę powinna ona zostać dodana przez najmłodszą, czyli przed 30, a u mnie została dodana jako pierwsza zamiast między 50, a 30.

Screenshot 2024-01-11 211631.png

3

a u mnie została dodana jako pierwsza zamiast między 50, a 30

Dzieje się tak gdyż zaraz w pierwszym warunku masz napisane, że jeśli pierwszy element jest starszy to wstaw nowy element jako pierwszy

if (glowa == nullptr || glowa->wiek >= wiek) {

Naprawienie tego warunku nie pomoże bo Twoja pętla jest tak skonstruowana

 while (aktualna != nullptr && aktualna->wiek < wiek) {

że nawet nie wejdziesz do jej ciała jeśli pierwszy element ma większy wiek niż nowy kwiat. A potem wykoansz to samo przypisanie co na samym początku, czyli wstawienie jako pierwsze.

To co musisz zrobić, to najpierw znaleźć element poprzedzający element z najniższym wiekiem przeczesując przy tym całą listę i dopiero wtedy możesz zacząć zamieniać wskaźniki.

(edit)
Funkcja po szybkich poprawkach może wyglądać w ten sposób i chyba powinno działać.

void wstawPrzedNajmlodsza(Roslina *&glowa, int wiek, string gatunek, float cena) {
    Roslina *nowaRoslina = new Roslina{wiek, gatunek, cena, nullptr};

    if (glowa == nullptr /*|| glowa->wiek >= wiek*/) {
        nowaRoslina->nastepna = glowa;
        glowa = nowaRoslina;
    } else {
        Roslina *aktualna = glowa;
        Roslina *poprzednia = nullptr;

        Roslina *przedZnaleziona = nullptr;
        Roslina *znaleziona = aktualna;
        
        while (aktualna != nullptr /*&& aktualna->wiek < wiek*/) {

            if(aktualna->wiek < znaleziona->wiek)
            {
                przedZnaleziona = poprzednia;
                znaleziona = aktualna;
            }

            poprzednia = aktualna;
            aktualna = aktualna->nastepna;
        }

        if (przedZnaleziona == nullptr) {
            nowaRoslina->nastepna = glowa;
            glowa = nowaRoslina;
        } else {
            nowaRoslina->nastepna = znaleziona;
            przedZnaleziona->nastepna = nowaRoslina;
        }
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1