// Prioriteettijonon toteutus #include "prioriteettijono.hh" // Jonon rakenne: jono_ osoittaa jonon ensimmäiseen alkioon tai on 0. // 0 tarkoittaa jonon loppua. Jono pidetään järjestyksessä, jossa tärkein // alkio on ensimmäisenä. // Läpikäynnissä lisäyksessä ja poistossa käytetään osoitinta osoittimeen // seuraavasti. // Olkoon Alkio **kohta = &jono_; // kohta osoittaa jäsenmuuttujaan, joka osoittaa ensimmäiseen alkioon. // *kohta osoittaa siis ensimmäiseen alkioon // (*kohta)->tarkeys on siten ensimmäisen alkion tärkeys. // // Jos ennen ensimmäistä alkiota halutaan lisätä alkio: // 1) uusialkio.seuraava = *kohta; eli uutta alkiota seuraa (vanha) // ensimmäinen alkio // 2) *kohta = uusialkio; eli muutetaan jono_ osoittamaan uuteen alkion // 3) Alkiot lisätään yksi kerrallaan, joten silmukka loppuu. // // Jos ensimmäinen alkio halutaan poistaa: // 1) Alkio *tmp = *kohta; otetaan ensimmäisen alkion osoite talteen // 2) *kohta = (*kohta)->seuraava; eli jono_ muutetaan osoittamaan toiseen // alkioon (tai NULL:ksi). // 3) delete tmp; poistetaan ensimmäinen alkio // 4) Poiston jälkeen *kohta osoittaa seuraavaan alkioon. Siksi jos alkio // poistetaan, ei sen jälkeen enää pidä siirtyä erikseen seuraavaan. // Tyhjän jonon alustus, jono_ = nollaosoitin tarkoittaa ettei ole termejä Prioriteettijono::Prioriteettijono(): jono_(NULL) {} // Vapautetaan varattu muisti Prioriteettijono::~Prioriteettijono() { Alkio *alkio = jono_; // Jonon loppu on merkitty nollaosoittimella while (alkio != NULL) { // Haetaan seuraava alkio ennen nykyisen poistamista Alkio *poistettava = alkio; alkio = alkio->seuraava; delete poistettava; poistettava = 0; } jono_ = NULL; } // Lisää uuden alkion jonoon oikeaan kohtaan. // Lisäysalgoritmista esimerkki tiedoston alussa void Prioriteettijono::lisaa(const Prioriteetti tarkeys, const string &viesti) { // Etsitään alkiolle oikea kohta jonosta. // Koska tapahtumat pidetään myös lisäysjärjestyksessä, lisätään // viimeisen samaa tai ylempää prioriteettia olevan jälkeen. // Osoitin lisäyskohtaa edeltävän alkion seuraavaan osoittavaan // osoittimeen. Alkio **lisayskohta = &jono_; // Jonon loppuessa kesken silmukka päättyy siten, että lisayskohta // osoittaa jonon viimeisen alkion sisältämään osoittimeen. while (*lisayskohta != NULL) { if ((*lisayskohta)->tarkeys > tarkeys) { // Seuraavan alkion tärkeys olisi pienempi (eli suurempi luku) // kuin lisättävän tärkeys -> tämä on haluttu kohta break; } lisayskohta = &((*lisayskohta)->seuraava); } // Lisätään alkio siten, että uusi alkio osoittaa *lisayskohtaan, // ja *lisayskohta (eli siis edellisen .seuraava-osoitin) osoittaa // lisättävään alkioon. Alkio *lisattava = new Alkio; lisattava->tarkeys = tarkeys; lisattava->viesti = viesti; lisattava->seuraava = *lisayskohta; *lisayskohta = lisattava; } // Poistaa kaikki prioriteettia tarkeys olevat alkiot ja palauttaa // poistettujen määrän. // Poistoalgoritmista on esimerkki tiedoston alussa. int Prioriteettijono::poista(const Prioriteetti tarkeys) { Alkio **poistokohta = &jono_; int poistetut = 0; while (*poistokohta != NULL) { if ((*poistokohta)->tarkeys == tarkeys) { Alkio *poistettava = *poistokohta; *poistokohta = (*poistokohta)->seuraava; delete poistettava; poistettava = 0; poistetut += 1; } else { // Poistossa siirrytään seuraavaan automaattisesti, muussa // tapauksessa tehdään se tässä. poistokohta = &((*poistokohta)->seuraava); } } return poistetut; } // Poistaa kaikki alkiot joiden viestissä on osamerkkijonona haku // Ikävä copypastekoodi, mutta ei jaksanut hienostella. int Prioriteettijono::poista(const string &haku) { Alkio **poistokohta = &jono_; int poistetut = 0; while (*poistokohta != NULL) { if ((*poistokohta)->viesti.find(haku) != string::npos) { Alkio *poistettava = *poistokohta; *poistokohta = (*poistokohta)->seuraava; delete poistettava; poistettava = 0; poistetut += 1; } else { // Poistossa siirrytään seuraavaan automaattisesti, muussa // tapauksessa tehdään se tässä. poistokohta = &((*poistokohta)->seuraava); } } return poistetut; } // Tulostaa kaikki alkiot void Prioriteettijono::tulosta(ostream &virta) const { const Alkio *kohta = jono_; while (kohta != NULL) { virta << kohta->tarkeys << ": " << kohta->viesti << std::endl; kohta = kohta->seuraava; } } // Tulostaa alkiot joiden prioriteetti on annettu void Prioriteettijono::etsi(const Prioriteetti prioriteetti, ostream &virta) const { const Alkio *kohta = jono_; while (kohta != NULL) { if (kohta->tarkeys == prioriteetti) { virta << kohta->tarkeys << ": " << kohta->viesti << std::endl; } kohta = kohta->seuraava; } } // Poistaa kiireellisimmän tapahtuman, kuvausteksti viiteparametrin kautta. // Tyhjä jono -> false, muutoin true bool Prioriteettijono::tarkein(string &kuvaus) { if (jono_ == NULL) { return false; } Alkio *poistettava = jono_; kuvaus = jono_->viesti; jono_ = jono_->seuraava; delete poistettava; poistettava = 0; return true; } // Palauttaa true jos jono on tyhjä bool Prioriteettijono::tyhja() const { return jono_ == NULL; } // Palauttaa jonon koon int Prioriteettijono::koko() const { int maara = 0; Alkio *kohta = jono_; while (kohta != NULL) { maara += 1; kohta = kohta->seuraava; } return maara; }