12
SPA1 - jednostruko povezane liste (3) Doni Pracner Contents Jednostruko povezane liste (treći deo) 1 Osnovne definicije sa prethodnih časova ................. 1 Lista kao klasa ............................... 2 Korišćenje primera operacija sa listama ................. 3 Lista objekata ................................ 6 Obrtanje liste ................................ 7 Liste različitih objekata .......................... 8 Sortirane liste različitih elemenata .................... 9 Sortirana lista sa ponavljanjem elemenata ................ 12 KRAJ trećeg dela 12 Jednostruko povezane liste (treći deo) Strukture podataka i algoritmi 1 Doni Pracner @DoniPracner | [email protected] Osnovne definicije sa prethodnih časova Definišemo klasu koja predstavlja jedan element liste, u njoj je info odgovara- jućeg tipa (int u primeru) i veza na sledeći element: 1

spa1-liste3

Embed Size (px)

DESCRIPTION

Strukture podataka i algorititmi.PredavnjeKurbalija VladimirPrirodno Matematicki Fakultet Novi Sad. 2015 Programiranje u programskom jeziku java

Citation preview

  • SPA1 - jednostruko povezane liste (3)

    Doni Pracner

    Contents

    Jednostruko povezane liste (trei deo) 1

    Osnovne definicije sa prethodnih asova . . . . . . . . . . . . . . . . . 1

    Lista kao klasa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    Korienje primera operacija sa listama . . . . . . . . . . . . . . . . . 3

    Lista objekata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    Obrtanje liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

    Liste razliitih objekata . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    Sortirane liste razliitih elemenata . . . . . . . . . . . . . . . . . . . . 9

    Sortirana lista sa ponavljanjem elemenata . . . . . . . . . . . . . . . . 12

    KRAJ treeg dela 12

    Jednostruko povezane liste (trei deo)

    Strukture podataka i algoritmi 1

    Doni Pracner@DoniPracner | [email protected]

    Osnovne definicije sa prethodnih asova

    Definiemo klasu koja predstavlja jedan element liste, u njoj je info odgovara-jueg tipa (int u primeru) i veza na sledei element:

    1

  • class Element {int info;Element veza;

    public Element(int br) {this.info = br;this.veza = null;

    }

    public String toString(){return info+"";

    }}

    Lista kao klasa

    class ListaBrojeva {

    // definisemo Element kao svoju unutrasnju klasu// umanjujemo mogucnost mesanja imena// sa nekom drugom klasomclass Element {

    ....}

    //pokazivac na prvi element listeElement prvi;

    /** Kreira praznu listu brojeva. */public ListaBrojeva() {

    this.prvi = null;}

    ....}

    Dodavanje novog elementa na poetak listepublic void dodajNaPocetak(int br) {

    Element novi = new Element(br);novi.veza = prvi;prvi = novi;

    }

    toString je primer prolaska kroz sve elemente listepublic String toString() {

    String rez = "Lista: [ ";Element tekuci = prvi;

    2

  • while (tekuci != null) {rez += tekuci.info + " ";tekuci = tekuci.veza;

    }rez += "]";return rez;

    }

    Lista [ ]Lista [ 1 ]Lista [ 1 2 3 ]

    Korienje primera operacija sa listama

    Program ListePrimeriOperacija koristi klasu ListaBrojevaBr sa prologasa.public class ListePrimeriOperacija {

    static ListaBrojevaBr lista;

    public static void main(String[] args) {....}

    .... // drugi pomocni metodi

    }

    Osnovna ideja glavnog programa:public static void main(String[] args) {

    lista = new ListaBrojevaBr();// inicijalizujemo listu

    char menu = 'a';while (menu != 'Q') {

    //stampanje menija.....menu = Svetovid.in.readChar();menu = Character.toUpperCase(menu);switch (menu) {.....}//pauza pre nastavljanjaif (menu != 'Q') {

    Svetovid.out.println(" -- enter za povratak u meni --");

    Svetovid.in.readLine();}

    } // while}

    tampanje menija:

    3

  • System.out.println();System.out.println("Ilustracija rada sa listama brojeva");System.out.println(

    "======================================");System.out.println("s-Stampa");System.out.println("u-Unos liste");System.out.println("k-Stampanje k-tog elementa");System.out.println("d-dodavanje elementa na pocetak");System.out.println("o-dodavanje elementa na k-to mesto");System.out.println("i-Izbacivanje br iz liste");System.out.println("v-Izbacivanje svih br iz liste");System.out.println("e-Izbacivanje k-tog elementa");System.out.println("m-Minimalni broj u listi");System.out.println("p-Pretraga elementa u listi");System.out.println();System.out.println("q-Kraj rada (Quit)");

    Odabir odgovarajue operacije:int brojswitch (menu) {case 'S':

    lista.stampajNaEkran();break;

    case 'U':unosBrojeva();break;

    case 'D':broj = Svetovid.in.readInt("Broj:");lista.dodajNaPocetak(broj);break;

    case 'O':broj = Svetovid.in.readInt("Broj koji dodajete:");int pos = Svetovid.in.readInt("Pozicija:");lista.dodaj(broj, pos);break;

    case 'I':izbacivanjeEl();break;

    case 'V':izbacivanjeElSvi();break;

    case 'E':izbacivanjeK();break;

    case 'K':stampajK();break;

    case 'M':

    4

  • Svetovid.out.println("Minimum liste je:"+ lista.minimum());

    break;case 'P':

    pretraga();break;

    default:// ne radimo nita inacebreak;

    }

    static void unosBrojeva() {System.out.println("unesite n (broj brojeva): ");int n = Svetovid.in.readInt();System.out.println("unesite brojeve");for (int i = 0; i < n; i++) {

    int br = Svetovid.in.readInt();lista.dodajNaPocetak(br);

    }}

    static void pretraga() {int broj = Svetovid.in.readInt(

    "Unesite broj koji trazite:");if (lista.uListi(broj)) {

    Svetovid.out.println("Broj postoji u listi");} else {

    Svetovid.out.println("Broj ne postoji u listi");}

    }

    Nalaenje elementa moe da baci izuzetak to je poeljno uhvatiti, naroito uprogramu koji je interaktivan.static void stampajK() {

    int broj = Svetovid.in.readInt("Unesite redni broj elementa koji zelite:");

    try {Svetovid.out.println("Element na mestu " + broj

    + " je " + lista.element(broj));} catch (Exception e) {

    Svetovid.out.println("Greska: " + e.getMessage());}

    }

    static void izbacivanjeK() {int broj = Svetovid.in.readInt(

    "Unesite poziciju koju treba izbaciti:");if (lista.izbaciK(broj)) {

    5

  • Svetovid.out.println("Pozicija je izbacena iz liste");

    } else {Svetovid.out.println("Pozicija ne postoji u listi");

    }}

    static void izbacivanjeEl() {int broj = Svetovid.in.readInt("Unesite broj koji treba izbaciti:");if (lista.izbaciIzListe(broj)) {

    Svetovid.out.println("Broj je izbacen iz liste");} else {

    Svetovid.out.println("Broj ne postoji u listi");}

    }

    static void izbacivanjeElSvi() {int broj = Svetovid.in.readInt("Unesite broj koji treba izbaciti:");

    Svetovid.out.println("Izbaceno je "+ lista.izbaciIzListeSve(broj) + "brojeva");

    }

    Lista objekata Dosada je u primerima info bio tipa int U principu moe biti proizvoljnog tipa Potrebno je samo promeniti tipove na adekvatnim mestima

    class ListaStringova {class Element {

    String info; //tipElement veza;public Element(String s) { //tip

    this.info = s;this.veza = null;

    }public String toString() {

    return info + "";}

    }

    Element prvi = null;

    public void dodaj(String s) { //tip

    6

  • ....}

    ....}

    toString metod se ne mora menjati, poto se konverzije deavaju automatski.Meutim esto je poeljno da se u zavisnosti od potreba doteraju separatorielemenata.public String toString() {

    String rez = "Lista: [ ";Element tekuci = prvi;while (tekuci != null) {

    rez += '"'+ tekuci.info + "\" ";//dodati ""tekuci = tekuci.veza;

    }rez += "]";return rez;

    }

    Primer izvravanja:Lista: [ "poslednji" "nista" "svasta" "neki el" "prvi" ]

    Obrtanje liste Dodavanje na poetak rezultuje listom unazad Ako je bitan redosled moemo dodavati na kraj

    Za efikasne operacije - dodatni pokaziva poslednji Mana: moramo paziti na dva specijalna pokazivaa

    Alternativno moemo naknadno obrnuti listu (naroito kad znamo da sesav unos deava na poetku programa)

    public void obrniListu() {if (prvi == null || prvi.veza == null) {

    //znaci da nemamo sta da radimoreturn;

    }

    //postoje bar 2 elementaElement preth = null;Element tek = prvi;

    while (tek != null) {Element sled = tek.veza;

    tek.veza = preth;

    7

  • preth = tek;tek = sled;

    }prvi = preth;

    }

    ListaStringovaOb lista = new ListaStringovaOb();lista.dodaj("prvi");lista.dodaj("neki el");lista.dodaj("svasta");lista.dodaj("nista");lista.dodaj("poslednji");

    System.out.println(lista);

    lista.obrniListu();

    System.out.println(lista);

    Lista: [ "poslednji" "nista" "svasta" "neki el" "prvi" ]Lista: [ "prvi" "neki el" "svasta" "nista" "poslednji" ]

    Liste razliitih objekata Nekad je potrebno uvati samo razliite elemente Dodavanje elementa kakav ve postoji nee promeniti listu Ako postoji operacija za proveru da li element postoji, promena u dodavanju

    je trivijalna

    public void dodaj(String s) {if (!uListi(s)) {

    Element novi = new Element(s);novi.veza = prvi;prvi = novi;

    }}

    Budui da uListi prolazi uvek kroz celu listu, dobijamo da je sada ubacivanjeznaano sporije - O(n).

    Analogno bi se promenilo bilo kakvo drugo dodavanje u listu.

    Ostale operacije nad listom e funkcionisati ispravno bez nekih promena, potoim nije bitno da li postoje duplikati u listi.

    Operacija izbaciIzListeSve e na primer nepotrebno ii do kraja liste ako jeve izbacila neto, ali e raditi ispravno.

    8

  • ListaRazlicitihStringova list =new ListaRazlicitihStringova();

    list.dodaj("mango");list.dodaj("mango");list.dodaj("ananas");list.dodaj("mango");list.dodaj("banana");list.dodaj("jabuka");

    System.out.println(list);

    Lista: [ jabuka banana ananas mango ]

    System.out.println(list);System.out.println("u listi mango:" + list.uListi("mango"));System.out.println("u listi krastavac:"

    + list.uListi("krastavac"));

    System.out.println();

    System.out.println("izbaci krastavac:"+ list.izbaci("krastavac"));

    System.out.println("izbaci mango:" + list.izbaci("mango"));System.out.println(list);

    Lista: [ jabuka banana ananas mango ]u listi mango:trueu listi krastavac:false

    izbaci krastavac:falseizbaci mango:trueLista: [ jabuka banana ananas ]

    Sortirane liste razliitih elemenata Nekad je bitno da su podaci sortirani na odreeni nain Takoe se operacije pretraivanja mogu obavljati efikasnije Formiranjem liste na odreeni nain se ovo lako postie

    Element se dodaje na poetak ako je lista prazna ili je novi manji odprvog

    Ako element postoji u listi ne dodaje se Inae se element ubacuje nakon poslednjeg elementa koji je manji od

    novog

    public void dodaj(String s) {if (prvi == null || prvi.info.compareTo(s) > 0) {

    Element novi = new Element(s);

    9

  • novi.veza = prvi;prvi = novi;

    } else {

    if (!prvi.info.equals(s)) {Element prethodni = prvi;

    while (prethodni.veza != null&& prethodni.veza.info.compareTo(s) < 0) {

    prethodni = prethodni.veza;}if (prethodni.veza == null

    || !prethodni.veza.info.equals(s)) {Element novi = new Element(s);novi.veza = prethodni.veza;prethodni.veza = novi;

    }}

    }//else}

    /** Vraca da li String {@code s} postoji u listi. */public boolean uListi(String s) {

    Element tekuci = prvi;while (tekuci != null && tekuci.info.compareTo(s) < 0) {

    tekuci = tekuci.veza;}

    // da li smo trenutno na elementureturn tekuci != null && tekuci.info.equals(s);

    }

    Ovakvo pretraivanje je i dalje O(n), ali je u svakako bre nego traenje u celojlisti.

    Izbacivanje se takoe moe ubrzati:/*** Izbacuje string 's' iz liste, naravno ako postoji i* vraca da li je operacija uspesno obavljena.*/public boolean izbaci(String s) {

    // proverimo da li je prvi elementif (prvi != null && prvi.info.equals(s)) {

    prvi = prvi.veza;return true;

    } else {

    /* trazimo u ostatku liste */Element tekuci, prethodni;

    10

  • tekuci = prvi;prethodni = null;while (tekuci != null

    && tekuci.info.compareTo(s) < 0) {/* do kraja liste ili dok ne nadjemo string */prethodni = tekuci;tekuci = tekuci.veza;

    }if (tekuci != null && tekuci.info.equals(s)) {

    /* nismo na kraju liste - nasli smo element,* prevezemo listu oko elementa */prethodni.veza = tekuci.veza;return true;

    } else {return false;

    }}

    }

    SortiranaListaRazlicitihStringova solist =new SortiranaListaRazlicitihStringova();

    solist.dodaj("mango");solist.dodaj("mango");solist.dodaj("ananas");solist.dodaj("mango");solist.dodaj("banana");solist.dodaj("jabuka");

    System.out.println(solist);

    Izvravanje:Lista: [ ananas banana jabuka mango ]

    System.out.println(solist);System.out.println("u listi mango:" + solist.uListi("mango"));System.out.println("u listi krastavac:"

    + solist.uListi("krastavac"));System.out.println();System.out.println("izbaci krastavac:"

    + solist.izbaci("krastavac"));System.out.println("izbaci mango:" + solist.izbaci("mango"));System.out.println(solist);

    Rezultat:Lista: [ ananas banana jabuka mango ]u listi mango:trueu listi krastavac:false

    11

  • izbaci krastavac:falseizbaci mango:trueLista: [ ananas banana jabuka ]

    Sortirana lista sa ponavljanjem elemenata Elementi liste su sortirani (obino neopadajue) Dozvoljeno je da postoji vie primeraka istog elementa Novi element se ubacuje

    na poetak ako je lista prazna ili je novi manji od prvog inae nakon svih elemenata koji su manji od novog

    Moe se ubrati metod za izbacivanje svih pojava elementa Implementacija se ostavlja za samostalnu vebu

    KRAJ treeg dela

    12

    Jednostruko povezane liste (trei deo)Osnovne definicije sa prethodnih asovaLista kao klasaKorienje primera operacija sa listamaLista objekataObrtanje listeListe razliitih objekataSortirane liste razliitih elemenataSortirana lista sa ponavljanjem elemenata

    KRAJ treeg dela