Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Rozdział 45 zadanie domowe

Ostatnio zmodyfikowano 2019-02-23 18:46
Autor Wiadomość
lukaszse
Temat założony przez niniejszego użytkownika
Rozdział 45 zadanie domowe
» 2019-02-19 23:23:22
W poniższym kodzie, aby dodać element na początek listy, liczby przesuwane są między węzłami. Kod działa poprawnie, ale wymaga dwukrotnego przejścia przez całą listę (próbowałem zoptymalizowąć aby dało się to zrobić za jednym razem, myślę że dało by rady).

C/C++
// Zwroc wskaznik na pierwszy element listy
Lista * pierwszy( Lista * lista )
{
    Lista * poczatek = new Lista;
    poczatek = lista;
   
    Lista * nowy_el = new Lista;
    nowy_el->liczba = 0;
    nowy_el->ogon = NULL;
   
    int temp1 = 0;
    int temp2 = 0;
   
   
   
    // Przechodzenie po liscie *iteracyjnie*
    if( lista )
    {
       
        while( lista->ogon )
        {
            lista = lista->ogon;
        }
       
        lista->ogon = nowy_el;
        lista = poczatek;
       
        temp1 = lista->liczba;
        while( lista->ogon )
        {
            lista = lista->ogon;
            temp2 = lista->liczba;
            lista->liczba = temp1;
            temp1 = temp2;
        }
       
    }
   
    lista = poczatek;
    //lista->liczba = 0;
    return lista;
}

// Dodaj element na poczatek listy
void dodajPoczatek( Lista *& lista, int liczba )
{
    // Tworzymy nowy element listy
    Lista * nowy = new Lista;
    nowy->liczba = liczba;
    nowy->ogon = NULL;
   
    // Dopisujemy na koniec
    if( lista )
    {
        //lista->ogon = lista;
        pierwszy( lista )->liczba = nowy->liczba;
    }
   
    else
         lista = nowy;
   
}


Nie działa natomiast kod w którym chciałem cały nowy węzeł dodać na początek. Wygląda to tak jak bym się zapętlił, tj. jakby wskaźnik ogon odwoływał się do swojego węzła w którym się znajduje, ale starałem się żeby tak nie było. Proszę o pomoc. Czy w ogóle ma to szansę zadziałać w ten sposób?

C/C++
// Zwroc wskaznik na pierwszy element listy
Lista * pierwszy( Lista * lista )
{
    Lista * nowy_el = new Lista;
    nowy_el->liczba = 0;
    nowy_el->ogon = lista;
    lista = nowy_el;
   
    return lista;
}

// Dodaj element na poczatek listy
void dodajPoczatek( Lista *& lista, int liczba )
{
    // Tworzymy nowy element listy
    Lista * nowy = new Lista;
    nowy->liczba = liczba;
    nowy->ogon = NULL;
   
    // Dopisujemy na koniec
    if( lista )
    {
        //lista->ogon = lista;
        pierwszy( lista )->liczba = nowy->liczba;
    }
   
    else
         lista = nowy;
   
}
P-174014
pekfos
» 2019-02-19 23:29:52
Dlaczego tworzysz nowy element listy dwa razy? Na dobrą sprawę wystarczy jak poprawisz te 3 linijki
C/C++
Lista * nowy = new Lista;
nowy->liczba = liczba;
nowy->ogon = NULL;
i to będzie kompletne wstawianie na początek listy. Wstawianie na początek listy jednokierunkowej jest bez porównania łatwiejsze od wstawiania na koniec, więc cały ten skopiowany kod się nie przyda.
P-174015
lukaszse
Temat założony przez niniejszego użytkownika
Rozdział 45. Zadanie domowe podpunkt 2
» 2019-02-23 18:26:09
Dzięki, ppkt 1 rzeczywiście okazał się łatwy. Niestety mam problem z podpunktem 2.

Przewertowałem forum, m.in temat http://cpp0x.pl/forum/temat/?id=26935&p=3
Niestety przedstawione w tym wątku rozwiązanie, wg mnie nie jest dobre (nie używa dodatkowego struct, a jedynie dodatkowe wskażniki na koniec).

Mój program jednak też nie chce działać... Co zrobiłem źle?

C/C++
#include <iostream>


struct Wezel
{
    Wezel * ogon;
    int liczba;
};

struct Lista
{
    Wezel * poczatek;
    Wezel * koniec;
};



void utworz( Lista & lista )
{
    Wezel * wezel;
    wezel = NULL;
   
    lista.poczatek = NULL;
    lista.koniec = NULL;
   
    Wezel * nowy = new Wezel;
   
    int liczba;
    char znak;
   
    std::cout << "Nazisnij\n(p) - dodaj na poczatek\n(k) - dodaj na koniec\n(z) - zakoncz i wypisz\n";
    std::cin >> znak;
   
    while( znak != 'z' )
    {
        switch( znak )
        {
        case 'p': //dodawanie na poczatek listy
            std::cout << "Podaj liczby na poczatek, 0 lub blad konczy:\n";
            while( std::cin >> liczba && liczba );
           
            {
               
                nowy->liczba = liczba;
                nowy->ogon = NULL;
               
                if( lista.poczatek )
                {
                    wezel = lista.poczatek;
                    nowy->ogon = wezel;
                    wezel = nowy;
                    lista.poczatek = wezel;
                   
                } else
                {
                    wezel = nowy;
                    lista.poczatek = wezel;
                }
            }
           
            break;
           
        case 'k': nowy->liczba = liczba;
            nowy->ogon = NULL; //dodawanie na koniec
            std::cout << "Podaj liczby na koniec, 0 lub blad konczy:\n";
            while( std::cin >> liczba && liczba );
           
            {
                nowy->liczba = liczba;
                nowy->ogon = NULL;
               
                if( lista.poczatek )
                {
                    if( lista.koniec )
                         wezel = lista.koniec;
                   
                    while( wezel->ogon )
                         wezel = wezel->ogon;
                   
                    wezel->ogon = nowy;
                    lista.koniec = wezel->ogon;
                   
                } else
                {
                    wezel = nowy;
                    lista.poczatek = wezel;
                }
            }
            break;
           
        case 'z':
            break;
           
        }
       
        std::cout << "Nazisnij\n(p) - dodaj na poczatek\n(k) - dodaj na koniec\n(z) - zakoncz i wypisz\n";
        std::cin >> znak;
    }
} // koniec void utworz


// Wypisz wszystkie elementy listy
void wypisz( Lista & lista )
{
   
    if( lista.poczatek )
    {
        Wezel * wezel = lista.poczatek;
       
        while( wezel->ogon )
        {
            std::cout << wezel->liczba << ", ";
            wezel = wezel->ogon;
        }
    }
} // koniec void wypisz




// Usuwa liste
void zniszcz( Lista lista )
{
    Wezel * wezel;
    wezel = lista.poczatek;
   
    while( lista.poczatek )
    {
        Wezel * tmp = wezel;
        wezel = wezel->ogon;
        delete tmp;
    }
   
    wezel = NULL;
} //koniec void zniszcz


int main()
{
    int liczba;
    Lista lista;
   
    utworz( lista );
    wypisz( lista );
    zniszcz( lista );
   
    return 0;
}
P-174065
pekfos
» 2019-02-23 18:46:08
Po pierwsze - rozwiązanie jest nie na temat. W zadaniu są podane funkcje do napisania i to jest bezwzględne wymaganie. Funkcja może robić za dużo i twoje utworz() się do takich zalicza.

Poza tym:
C/C++
while( std::cin >> liczba && liczba );

{
Średnik.

C/C++
while( lista.poczatek )
{
    Wezel * tmp = wezel;
    wezel = wezel->ogon;
    delete tmp;
}
Pętla nieskończona.
P-174066
« 1 »
  Strona 1 z 1