Sortowanie listy jednokierunkowej w książce telefonicznej

0

Witam, posiadam tak napisany algorytm książki telefonicznej. Brakuje mi niestety w nim jednej opcji. Moim zadaniem jest wyświetlenie kontaktów w kolejności alfabetycznej względem nazwisk. Niestety to zadanie mnie przerasta.

#include <iostream>
#include <string>
using namespace std;

void dodaj_osobe();
void wyszukaj_nazwisko();
void pokaz_wszystkie();
void usun_osobe();

struct osoba
{
    string imie;
    string nazwisko;
    string telefon;
    bool isdelete;
    osoba * next;
    osoba()
    {
        delete next;
    }
};
osoba * poczatek = NULL;

int main()
{


    int litera = 0;
    do
    {
        cout << "___________________________________"<<endl;
        cout << "Program tworzy książkę telefoniczną" << endl;
        cout << "Wpisz odpowiednie liczby aby wykonać dane czynności" << endl;
        cout << "1. Dodaj osobę" << endl;
        cout << "2. Wyszukaj osobę po nazwisku" << endl;
        cout << "3. Pokaż listę osób" << endl;
        cout << "4. Zakoncz program" << endl;
        cout << "___________________________________"<<endl;
        cin >> litera;
        cout << "Wybrałeś/aś opcję " << litera <<endl;
       
        switch( litera )
        {

           
        case 1:
            dodaj_osobe();
            break;
           
        case 2:
            wyszukaj_nazwisko();
            break;
           
        case 3:
            pokaz_wszystkie();
            break;
           
        case 4:
            cout << " KONIEC PROGRAMU " << endl;
            break;
           
            default:
            cout << " Wybrałeś/aś opcję niedozwoloną >>" << endl;
            cout << " Wybierz jeszcze raz odpowiednią opcję >>" << endl;
            break;
        }
    } while( litera != 0 );
   
    return 0;
}


void dodaj_osobe()
{
    osoba * nowa = new osoba;
    nowa->next = NULL;
    cout << "Podaj imię ";
    cin >> nowa->imie;
    cout << "Podaj nazwisko \t";
    cin >> nowa->nazwisko;
    cout << "Podaj numer telefonu \t";
    cin >> nowa->telefon;
    nowa->isdelete = true;
    if( poczatek == NULL )
    {
        poczatek = nowa;
    }
    else
    {
        osoba * szukaj = poczatek;
        while( szukaj->next != NULL )
        {
            szukaj = szukaj->next;
        }
        szukaj->next = nowa;
    }
}

void wyszukaj_nazwisko()
{
    string szukacz;
    cout << "Podaj nazwisko do wyszukania \t";
    cin >> szukacz;
    osoba * pokaz = poczatek;
    while( pokaz->next != NULL )
    {
        if( pokaz->nazwisko == szukacz )
        {
            cout << "Imię: " << pokaz->imie << endl
            << "Nazwisko: " << pokaz->nazwisko << endl
            << "Telefon: " << pokaz->telefon << endl;
        }
        pokaz = pokaz->next;
    }
    if( pokaz->nazwisko == szukacz )
    {
        cout << "Imię: " << pokaz->imie << endl
        << "Nazwisko: " << pokaz->nazwisko << endl
        << "Telefon: " << pokaz->telefon << endl;
    }
    else
    {
        cout << "Brak takiej osoby" << endl;
    }
}


void pokaz_wszystkie()
{
    if( poczatek != NULL )
    {
        osoba * pokaz = poczatek;
       
        while( pokaz->next != NULL )
        {
            cout << "-----\n" << pokaz->imie << endl;
            cout << pokaz->nazwisko << endl;
            cout << pokaz->telefon << endl;
            pokaz = pokaz->next;
            //}
        }
        cout << "-----\n" << pokaz->imie << endl;
        cout << pokaz->nazwisko << endl;
        cout << pokaz->telefon << endl;
       
    }
   
}


2

Masz ważne błędy w klasie, między innym w konstruktorze, delete wartości nieokreślonej to strzał w stopę.
Skądinąd niewykorzystany prawidłowo konstruktor (ma ustawić pola w sensowne wartości - nie kod zewnętrzny).
Kwiatki jak isdelete - najstarsi Indianie nie wiedzą co to twór.

Liczne powielenia kodu (te na wyjściu z pętli) - męczysz się obsługą 'next'. Zanim cokolwiek nastąpi z dodawaniem kodu (a sortowanie może być trudne), trzeba to oczyścić przez przerobienie pętli (i się nieco skróci)

0

Schemat podstawowej pętli do tego typu listy jest (w pseudokodzie):


wrk = root;
while(wrk != null){
  do something
  wrk = wrk-> next;
}

Przy czym działa poprawnie również dla pustej listy (root == null), nie trzeba (ale można z jakiś powodów, np drukowania specjalnego komunikatu) dawać if'a

2

Jeżeli nie musisz implementować listy na bazie wskaźników, to polecam użyć kontener std::list. Twój kod skróci się wtedy co najmniej o połowę.

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