C3

/**
 * Trieda zapuzdrujuca spajany zoznam a manipulaciu s nim
 */

public class SpajanyZoznam {

        /**
         * Sukromna trieda reprezentujuca jeden uzol spajaneho zoznamu
         */

        private static class Uzol {
                int hodnota;
                Uzol dalsi;
        }

        /**
         * Referencia na prvy uzol spajaneho zoznamu
         */

        private Uzol prvy = null;
        private Uzol posledny = null;
        // velkost nam bude sluzit na zistenie poctu ulozenych hodnot/uzlov
        // velkost volame pri metode size()
        private int velkost = 0;

        /**
         * Prida novu hodnotu na zaciatok spajaneho zoznamu
         *
         * @param hodnota
         *            pridavana hodnota
         */

        public void pridajNaZaciatok(int hodnota) {
                Uzol pridavany = new Uzol();
                pridavany.hodnota = hodnota;
                pridavany.dalsi = prvy;
                prvy = pridavany;
                if(velkost==0){
                        posledny=pridavany;
                }
                velkost++;
        }

        // casova zlozitost je O(n)
        private Uzol vratITy(int index) {
                Uzol aktualny = prvy;
                int pozicia = 0;
                while (aktualny != null) {
                        if (pozicia == index)
                                return aktualny;
                        aktualny = aktualny.dalsi;
                        pozicia++;
                }
                return null;
        }

        // O(n)
        public int get(int index) {
                Uzol ity = vratITy(index);
                if (ity == null) {
                        throw new IndexOutOfBoundsException();
                }
                return ity.hodnota;
        }

        public void set(int index, int value) {
                Uzol ity = vratITy(index);
                if (ity == null) {
                        throw new IndexOutOfBoundsException();
                }
                ity.hodnota = value;
        }

        public void add(int value) {
                Uzol novy = new Uzol();
                novy.hodnota = value;
                Uzol aktualny = prvy;
                if (prvy == null) {
                        prvy = novy;
                        velkost++;
                        return;
                }
                while (aktualny.dalsi != null) {
                        aktualny = aktualny.dalsi;
                }
                aktualny.dalsi = novy;
                posledny=novy;
                velkost++;
        }

        public void add(int index, int value) {
                if (index < 0 || index > velkost) {
                        throw new IndexOutOfBoundsException();
                }

                if (index == 0) {
                        this.pridajNaZaciatok(value);
                        //tu nepiseme velkost++ lebo pridaj
                        //na zaciatok to uz ma v sebe
                        return;
                }
                Uzol novy = new Uzol();
                novy.hodnota = value;
                Uzol ity = vratITy(index - 1);
                novy.dalsi = ity.dalsi;
                ity.dalsi = novy;
                if(velkost==index){
                        posledny=novy;
                }
                velkost++;
        }

        public int size(){
                return velkost;
        }

        public void remove(int index){
                if (index < 0 || index > velkost-1) {
                        throw new IndexOutOfBoundsException();
                }

                if(index==0){
                        prvy=prvy.dalsi;
                }
                else{
                        Uzol ity=vratITy(index-1);
                        ity.dalsi=ity.dalsi.dalsi;
                        if(index==velkost-1){
                                posledny=ity;
                        }
                }
                if(velkost==1){
                        posledny=null;
                }

                velkost--;

        }

        @Override
        public String toString() {
                String vysledok = "[";
                Uzol aktualny = prvy;
                while (aktualny != null) {
                        if (aktualny != prvy)
                                vysledok += ", ";

                        vysledok += aktualny.hodnota;
                        aktualny = aktualny.dalsi;
                }

                return vysledok + "]";
        }

        /**
         * Vrati sucet hodnot ulozenych v spajanom zozname
         */

        public int sucet() {
                // Referencia na uzol zoznamu, na ktorom sa prave nachadzame
                Uzol aktualny = prvy;
                // Premenna, v ktorej akumulujeme sucet
                int vysledok = 0;
                // Kym sme na nejakom uzle ...
                while (aktualny != null) {
                        // Priratame hodnotu uzla
                        vysledok += aktualny.hodnota;
                        // Presunieme sa na dalsi uzol v zozname
                        aktualny = aktualny.dalsi;
                }

                return vysledok;
        }

}

public class Spustac {

        /**
         * @param args
         */

        public static void main(String[] args) {
                // TODO Auto-generated method stub

                SpajanyZoznam sp=new SpajanyZoznam();
                sp.pridajNaZaciatok(5);
                System.out.println(sp);
                sp.set(0, 6);
                System.out.println(sp.get(0));
                sp.add(7);
                sp.add(1, 54);
                System.out.println(sp);
                System.out.println(sp.size());
                sp.remove(0);
                System.out.println(sp);
                System.out.println(sp.size());
        }

}