Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 01. 02. 2015 13:36

haha
Zelenáč
Příspěvky: 1
Škola: FJFI ČVUT
Pozice: Studentka
Reputace:   
 

Lineární spojový seznam - úkol C++

Ahoj, potřebovala bych pomoci s úkolem. Mám lineární spojový seznam a mám úkol - vypsat člověka s nejnižší váhou. Jenže nějak nevím, jak na to. Mohl by mi prosím někdo poradit?

Zdroják:

#include <iostream>
#include <stdlib.h>

using namespace std;

struct Clovek {
    short vek;
    float vaha;
    char jmeno[50];
    Clovek* dalsi;
};


void vypisCloveka(Clovek c)
{
    cout << c.vek << endl;
    cout << c.vaha << endl;
    cout << c.jmeno << endl;
}

void vypisNtehoCloveka(Clovek prvni, int N)
{
    if (N <= 0)
    {
        vypisCloveka(prvni);
    }
    else
    {
        Clovek* current = prvni.dalsi;
        for (int i = 1;i < N;i++)
        {
            if (current->dalsi != nullptr) // Nejsme na poslednim vagone?
            {
                current = current->dalsi; // Prechod k dalsimu vagonku
            }
            else
            { // Jsme na poslednim
                cout << "N je vetsi nez delka spojoveho seznamu" << endl;
                return;
            }
        }
        vypisCloveka(*current);
    }
}

void vlozDoSeznamu(Clovek* loko, Clovek* kdo) // Vlozi clovek "kdo" do spojoveho seznamu zacinajici "loko"
{
    Clovek* current = loko;
    while (current->dalsi != nullptr) // Dojde k poslednimu prvku seznamu
    {
        current = current->dalsi;
    }

    // Pripoji "kdo" za posledni prvek => "kdo" se stava poslednim prvkem
    current->dalsi = kdo;
    kdo->dalsi = nullptr;
}

int spocitejPrvky(Clovek prvni)
{
    int pocitadlo = 1;

    Clovek* current = &prvni;
    while (current->dalsi != nullptr)
    {
        pocitadlo = pocitadlo+1; // to stejne jako pocitadlo++
        current = current->dalsi;
    }

    return pocitadlo;
}

void vypisCelySeznam(Clovek prvni)
{
    Clovek* current = &prvni;
    do //Pouzijeme do-while aby se vypsal i prvni prvek (je-li v seznamu jediny)
    {
        vypisCloveka(*current);
            current = current->dalsi;
    }
    while (current->dalsi != nullptr);

    // Musime vypsat jeste toho posledniho
    vypisCloveka(*current);
}

Clovek* vratNtehoCloveka(Clovek* loko,unsigned int N)
{
   
    int pocitadlo = 1;
   
    Clovek* current = loko;
    while (current->dalsi != nullptr && pocitadlo != N) // dokud nejsme na konci a jeste jsme nedosahli N
    {
        pocitadlo = pocitadlo+1; // to stejne jako pocitadlo++
        current = current->dalsi;
    }
   
    return current;
}

void odstranZeSeznamu(Clovek* loko, int kolikaty)
{
    int pocetPrvku = spocitejPrvky(*loko);

    // Odstranujeme prvek nekde uvnitr vlaku?
    if (kolikaty > 1 && kolikaty < pocetPrvku)
    {
        Clovek* tenCoMazu = vratNtehoCloveka(loko,kolikaty);
        Clovek* tenPredNim = vratNtehoCloveka(loko, kolikaty-1);
        Clovek* tenZaNim = vratNtehoCloveka(loko, kolikaty+1);

        tenPredNim->dalsi = tenZaNim;

        delete tenCoMazu;
    }

    // Jsme na poslednim vagonu a je tam vic vagonu nez jen loko?
    if (kolikaty == pocetPrvku && pocetPrvku > 1)
    {
        Clovek* tenCoMazu = vratNtehoCloveka(loko,kolikaty);
        Clovek* tenPredNim = vratNtehoCloveka(loko, kolikaty-1);
       
        tenPredNim->dalsi = nullptr;
        delete tenCoMazu;
    }
}


void smazCelySeznam(Clovek* loko)
{

    Clovek* current = loko;
    while (current->dalsi != nullptr)
    {
        // Pozor abych si nesmazal neco, co jeste potrebuju
        Clovek* tenCoMazu = current;
        current = current->dalsi;
        delete tenCoMazu;
    }

    delete current;
}


void nactiCloveka(Clovek* kdo)
{
    cout << "Zadejte vek cloveka: " << endl;
    cin >> kdo->vek;

    cout << "Zadejte vahu cloveka: " << endl;
    cin >> kdo->vaha;

    cout << "Zadejte jmeno cloveka: " << endl;
    cin.ignore();
    gets_s(kdo->jmeno); // Tato funkce nam nacte retezec ze standardniho vstupu
    kdo->dalsi = nullptr;
}


Clovek* prvniPrvek = nullptr;


void main()
{
    for (int i=0;i<2;i++)
    {
        Clovek* novy = new Clovek;
        nactiCloveka(novy);
       
        if (prvniPrvek == nullptr)
        {
            prvniPrvek = novy;
        }
        else
        {
            vlozDoSeznamu(prvniPrvek,novy);
        }

        cout << "Clovek byl vlozen do seznamu." << endl;
    }

    cout << endl;
    cout << "Vypisuji seznam:" << endl;

    // Vsichni jsou uz jiz nacteni, vypis cely seznam
    vypisCelySeznam(*prvniPrvek);

    // Koncime praci s programem, takze smazeme seznam
    smazCelySeznam(prvniPrvek);

    int c;
    cin >> c;

    smazCelySeznam(prvniPrvek);

}

Offline

 

#2 02. 02. 2015 12:31

mb305
Příspěvky: 126
Pozice: nadšený student, který se má více učit
Reputace:   
 

Re: Lineární spojový seznam - úkol C++

Ahoj,

napadají mě dvě metody:

1/ Projít celý spojový seznam a člověka s nejnižší váhou najít. Zde bude složitost nalezení O(n) (protože musíš projít celý spojový seznam). Algoritmus by fungoval takto:
  - do pomocné proměnné si ulož prvního člověka
  - procházej prvky seznamu, když najdeš člověka s nižší váhou, ulož si ho do pomocné proměnné
  - vypiš data z pomocné proměnné

2/ Ukládat si lidi do spojového seznamu podle váhy. Při vkládání nového člověka najdeš pozici (podle váhy) kam patří a tam ho uložíš. Jen pozor na správné přesunutí ukazatelů na následující (popř. předchozí) prvek seznamu. Nejlehčí člověk pak budebyl ve spojovém seznamu na prvním místě. Proto by byla složitost nalezení nejlehčího člověka O(1) (protože bys vypsala pouze první prvek ze seznamu).

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson