Sunteți pe pagina 1din 11

Note de laborator Specializare

Algoritmi si structuri de date 2 Info 1

Laborator 8
Descriere: Structuri de date

1. Introducere

Scopul listelor este de a memora un ansamblu finit de elemente al caror numar nu este cunoscut
apriori. Listele sunt structuri de date dinamice, ın sensul ca numarul elementelor variaza in timpul
executiei programului, prin adaugari sau stergeri de elemente. Operatiile care pot fi efectuate pe o
lista sunt:
ƒ testarea daca lista este vida
ƒ adaugarea de elemente
ƒ verificarea daca un element este ın lista
ƒ stergerea unui element

1. Lista liniara

O lista liniara este o secventa finita (e0, ... , en-1) de elemente. Componentele unei liste nu trebuie sa
fie neaparat distincte; putem avea i ≠ j si ei = ej . Lungimea unei liste L = (e0, ... , en-1), notata cu
Lung(L), este data de numarul de componente din lista: Lung(L) = n. Lista vida ( ) este lista fara
nici o componenta (de lungime 0). Fiecare element al listei contine pe langa informatia efectiva si
adresa elementului urmator, numit si pointer. Java permite realizarea listelor cu ajutorul claselor si
obiectelor: celulele unei liste sunt obiecte ın care o variabila de clasa contine o referinta catre celula
urmatoare.

class Lista {

int continut;
Lista urmator;

Lista (int x, Lista a) {


continut = x;
urmator = a;
}
}

Instructiunea new Lista(x,a) construieste o noua celula cu campurile x si a. Metoda Lista(x,a)


este un constructor al clasei Lista. Pentru a marca sfarsitul liste, se foloseste null.

Exemplu: Lista 2, 7, 11 poate fi create folosind apelul


new Lista(2, new Lista(7, new Lista(11,null)))

1.1 Operatii

EsteVida. Testeaza daca o lista data este vida.


Intrare: o lista liniara L;
Iesire: true daca L = ( ),
false daca L ≠ ( ).
ASD

static boolean esteVida (Lista a) {


return a == null;
}

Adauga. Insereaza un element in capul listei


Intrare: o lista liniara L = (e0, ... , en-1), un element e
Iesire: L = (e, e0, ... , en-1)

static Lista adauga (int x, Lista a) {


return new Lista (x, a);
}

Cauta. Verifica daca un element dat x apare intr-o lista liniara data L. Metoda efectueaza o
parcurgere a listei. Variabila a este modificata iterativ prin a=a.urmator pentru a parcurge
elementele listei pana se gaseste x sau pana se gaseste sfarsitul listei (a = null)
Intrare: o lista liniara L = (e0, ... , en-1) si un element x
Iesire: false, daca x nu apare in L
true, daca x apare in L

static boolean cauta (int x, Lista a) {


while (a != null) {
if (a.continut == x)
return true;
a = a.urmator;
}
return false;
}

Lung. Intoarce lungimea unei listei date.


Intrare: o lista liniara L = (e0, ... , en-1) cu n ≥ 0
Iesire: n.

static int lungime(Lista a) {


if (a == null) return 0;
else return 1 + lungime(a.urmator);
}

Elimina. Elimina un element dat dintr-o lista liniara data. Eliminarea unei celule care contine x se
face modificand valoarea campului urmator continut ın predecesorul lui x: succesorul
predecesorului lui x devine succesorul lui x. Un tratament particular trebuie facut daca elementul
care trebuie eliminat este primul element din lista.
Intrare: o lista liniara L = (e0, ... , en-1) si un element x
Iesire: lista L din care s-au eliminat toate elementele ei egale cu x.

static Lista elimina (int x, Lista a) {


if (a != null)
if (a.continut == x)
a = a.urmator;
else
a.urmator = elimina (x, a.urmator);
return a;
}
ASD

2. Cozi

Cozile sunt liste liniare particulare utilizate ın programare pentru gestionarea obiectelor care sunt ın
asteptarea unei prelucrari ulerioare, de exemplu procesele de asteptare a resurselor unui sistem,
nodurile unui graf, etc. Elementele sunt adaugate sistematic la coada si sunt eliminate din capul
listei. Aceasta strategie este FIFO (First In First Out), ın opozitie cu strategia LIFO (Last In First
Out) utilizata la stive.

class Coada {

final static int MaxC = 100;


int inceput;
int sfarsit;
boolean plina, vida;
int info[];

Coada () {
inceput = 0;
sfarsit = 0;
plina= false;
vida = true;
info = new int[MaxC];
}

static Coada vida(){


return new Coada();
}

static void facVida (Coada c) {


c.inceput = 0;
c.sfarsit = 0;
c.plina = false;
c.vida = true;
}

static boolean esteVida(Coada c) {


return c.vida;
}

static boolean estePlina(Coada c) {


return c.plina;
}

static int primaValoare(Coada c) {


if (c.vida)
System.out.println("Coada Vida.");
return c.info[c.inceput];
}

static int ultimaValoare(Coada c) {


if (c.vida)
System.out.println("Coada Vida.");
return c.info[c.sfarsit-1];
}

private static int succesor(int i) {


return (i+1) % MaxC;
}

static void adaug(int x, Coada c) {


if (c.plina)
System.out.println("Coada Plina.");
ASD

c.info[c.sfarsit] = x;
c.sfarsit = succesor(c.sfarsit);
c.vida = false;
c.plina = c.sfarsit == c.inceput;
}

static void elimina (Coada c) {


if (c.vida)
System.out.println("Coada Vida.");

c.inceput = succesor(c.inceput);
c.vida = c.sfarsit == c.inceput;
c.plina = false;
}

public static void main(String [] args){


Coada cc= new Coada();
System.out.println("Adaugare");
adaug(4,cc);
adaug(6,cc);
adaug(7,cc);

System.out.println("Afisare prima si ultima valoare");


System.out.println(primaValoare(cc));
System.out.println(ultimaValoare(cc));

System.out.println("Elimina primul element");


elimina(cc);

System.out.println("Afisare prima si ultima valoare");


System.out.println(primaValoare(cc));
System.out.println(ultimaValoare(cc));
}
}

2. Stive

Notiunea de stiva intervine ın mod curent ın programare, rolul sau principal fiind la implementarea
apelurilor de proceduri. O stiva se poate imagina ca o cutie ın care sunt plasate obiecte si din care
se scot ın ordinea inversa fata de cum au fost introduse: obiectele sunt puse unul peste altul ın cutie
si se poate avea acces numai la obiectul situat ın varful stivei. Realizarea operatiilor asupra stivelor
se poate face utilizand un tablou care contine elementele si un indice care indica pozitia varfului
stivei.

class Stiva {

final static int maxP = 100;


int inaltime;
Element continut[];

Stiva() {
inaltime = 0;
continut = new Element[maxP];
}
ASD

static Stiva vid () {


return new Stiva();
}

static void facVida (Stiva s) {


s.inaltime = 0;
}

static boolean esteVida (Stiva s) {


return s.inaltime == 0;
}

static boolean estePlina (Stiva s) {


return s.inaltime == maxP;
}

static void adauga (Element x, Stiva s){


if (estePlina (s))
System.out.println("Stiva plina");

s.continut[s.inaltime] = x;
++s.inaltime;
}

static Element valoare (Stiva s){


if (esteVida (s))
System.out.println("Stiva vida");
return s.continut[s.inaltime-1];
}

static void sterge (Stiva s){


if (esteVida (s))
System.out.println("Stiva vida");
s.inaltime=0;
}

public static void main(String [] args){

Stiva ss = new Stiva();

adauga(new Element(false,4,' '),ss);


System.out.println(valoare(ss));

adauga(new Element(false,5,' '),ss);


System.out.println(valoare(ss));

adauga(new Element(true,0,'+'),ss);
System.out.println(valoare(ss));
}
}

class Element {
boolean esteOperator;
int valoare;
char simbol;

Element(boolean esteOperator, int valoare, char simbol){


this.esteOperator=esteOperator;
this.valoare=valoare;
this.simbol=simbol;
}
ASD

public String toString(){


if (!esteOperator) return valoare+"";
else return simbol+"";
}
}

Exemplu. Evaluarea expresiilor aritmetice prefixate

Vom ilustra utilizarea stivelor printr-un program de evaluare a expresiilor aritmetice scrise sub o
forma particulara. In programare o expresie aritmetica poate contine numere, variabile si operatii
aritmetice (ne vom limita numai la + si *). Vom considera ca intrari numai numere naturale.

Expresiile prefixate contin simbolurile: numere naturale, +, *, ( si ). Daca e1 si e2 sunt expresii


prefixate atunci (+e1e2) si (∗e1e2) sunt expresii prefixate. Pentru reprezentarea unei expresii
prefixate ın Java, vom utiliza un tablou ale carui elemente sunt entitatile expresiei. Elementele
tabloului sunt obiecte cu trei campuri: primul reprezinta natura entitatii (simbol sau numar), al
doilea reprezinta valoarea entitatii daca aceasta este numar, iar al treilea este este un simbol daca
entitatea este simbol.

class Element {
boolean esteOperator;
int valoare;
char simbol;

Element(boolean esteOperator, int valoare, char simbol){


this.esteOperator=esteOperator;
this.valoare=valoare;
this.simbol=simbol;
}

public String toString(){


if (!esteOperator) return valoare+"";
else return simbol+"";
}
}

Vom utiliza functiile definite pentru stiva si procedurile definite ın cele ce urmeaza.

static int calcul (char a, int x, int y) {


switch (a) {
case ’+’: return x + y;
case ’*’: return x * y;
}
return 1;
}

Procedura de evaluare consta ın stivuirea rezultatelor intermediare, stiva continand operatori si


numere, dar niciodata nu va contine consecutiv numere. Se examineaza succesiv entitatile expresiei
daca entitatea este un operator sau un numar si daca varful stivei este un operator, atunci se
plaseaza ın stiva. Daca este un numar si varful stivei este de asemenea un numar, actioneaza
operatorul care precede varful stivei asupra celor doua numere si se repeta operatia asupra
rezultatului gasit.

De exemplu, pentru expresia


(+ (+ (+ 35 36) (+ 5 6)) (^ (+ 7 8) (^ 9 9 )))

evaluarea decurge astfel:


ASD

9
5 7 ^ ^
35 + + + + 15 15
+ + 71 71 71 ^ ^ ^ ^ ^
* * * * * * 781 781 781 781 781 781
+ + + + + + + + + + + + +

Program complet

class Stiva {

final static int maxP = 100;


int inaltime;
Element continut[];

Stiva() {
inaltime = 0;
continut = new Element[maxP];
}

static Stiva vid () {


return new Stiva();
}

static void facVida (Stiva s) {


s.inaltime = 0;
}

static boolean esteVida (Stiva s) {


return s.inaltime == 0;
}

static boolean estePlina (Stiva s) {


return s.inaltime == maxP;
}

static void adauga (Element x, Stiva s){


if (estePlina (s))
System.out.println("Stiva plina");

s.continut[s.inaltime] = x;
++s.inaltime;
}

static Element valoare (Stiva s){


if (esteVida (s))
System.out.println("Stiva vida");
return s.continut[s.inaltime-1];
}

static void sterge (Stiva s){


if (esteVida (s))
System.out.println("Stiva vida");
s.inaltime--;
}

static int calcul (char a, int x, int y) {


switch (a) {
case '+': return x + y;
case '^': return x * y;
}
return 1;
ASD

static void insereaza (Element x, Stiva s) {

Element y, op;

while (!(esteVida(s) || x.esteOperator || valoare(s).esteOperator)){


y = valoare(s);
s.sterge(s);
op = valoare(s);
sterge(s);
x.valoare = calcul(op.simbol, x.valoare, y.valoare);
}
adauga(x,s);
}

static int calculeaza (Element u[]){

Stiva s = new Stiva();

for (int i = 0; i < u.length ; i++) {


insereaza(u[i], s);
}

return valoare(s).valoare;
}

public static void main (String args[]) {

Element exp[] = new Element [args.length];

for (int i = 0; i < args.length; i++) {


String s = args[i];

if (s.equals("+") || s.equals("^"))
exp[i] = new Element (true, 0, s.charAt(0));
else
exp[i] = new Element (false, Integer.parseInt(s), ' ');
}

System.out.println("Elemente");

for(int i=0;i<args.length;i++)
System.out.println(exp[i]);

System.out.println("===============");

System.out.println("Rezultat " + calculeaza(exp));

}
}

class Element {
boolean esteOperator;
int valoare;
char simbol;

Element(boolean esteOperator,int valoare, char simbol){


this.esteOperator=esteOperator;
this.valoare=valoare;
this.simbol=simbol;
}
ASD

public String toString(){


if (!esteOperator) return valoare+"";
else return simbol+"";
}
}

3. Colectii in Java (Vector)

import java.util.*;
import java.io.*;

class Test{
static Vector v;

public static void adauga(String s){


Integer obj=new Integer(s);
v.add(obj);
System.out.println("S-a adaugat!");
}

public static void sterge(String s){


Integer obj=new Integer(s);
if (v.contains(obj)){
v.remove(obj);
System.out.println("S-a sters!");
}
else
System.out.println("Elementul dat nu este in lista!");
}

public static void primul(){


Integer obj=(Integer)v.firstElement();
System.out.println("Primul element: "+obj.intValue());
}

public static void ultimul(){


Integer obj=(Integer)v.lastElement();
System.out.println("Ultimul element: "+obj.intValue());
}

public static void contine(String s){


Integer obj=new Integer(s);
if (v.contains(obj))
System.out.println("Da!");
else
System.out.println("Nu!");
}

public static void capacitate(){


System.out.println("Capacitate: "
+String.valueOf(v.capacity()));
}

public static void elementDePePozitie(int p){


try{
System.out.println("Elementul de pe pozitia "+p+": "+v.elementAt(p));
}catch(ArrayIndexOutOfBoundsException e){
System.err.println("Pe pozitia "+p+
" nu este nici un element!");}
}

public static void gaseste(String s){


Integer obj=new Integer(s);
if (v.indexOf(obj)!=-1)
ASD

System.out.println("Pozitia: "+
String.valueOf(v.indexOf(obj)+1));
else
System.out.println("Elementul nu este in vector");
}

public static void listeaza(){


Iterator i=v.iterator();
while(i.hasNext()){
Integer obj=(Integer)i.next();
System.out.println(String.valueOf(obj.intValue()));
}
}

public static void main(String[] args){


v=new Vector();
BufferedReader in=new BufferedReader(
new InputStreamReader(System.in));
int c;
try{
while(true){
System.out.println("1 - Adauga");
System.out.println("2 - Sterge");
System.out.println("3 - Test: contine elementul?");
System.out.println("4 - Gaseste element");
System.out.println("5 - Dimensiune");
System.out.println("6 - Primul element");
System.out.println("7 - Ultimul element");
System.out.println("8 - Element de pe o pozitie");
System.out.println("9 - Listeaza");
System.out.println("e - Iesire");

c=in.readLine().charAt(0);
switch(c){
case '1':
System.out.print("Dati elementul: ");
adauga(in.readLine());
break;
case '2':
System.out.print("Dati elementul: ");
sterge(in.readLine());
break;
case '3':
System.out.print("Dati elementul: ");
contine(in.readLine());
break;
case '4':
System.out.print("Dati elementul: ");
gaseste(in.readLine());
break;
case '5':
capacitate();
break;
case '6':
primul();
break;
case '7':
ultimul();
break;
case '8':
System.out.println("Dati pozitia: ");
int p=Integer.parseInt(in.readLine());
elementDePePozitie(p);
break;
case '9':
ASD

listeaza();
break;
case 'e':
System.exit(1);
}
}
}catch(NumberFormatException e){
System.err.println("Introduceti corect numerele!");
}catch(IOException e){}
}
}

Probleme

1. Realizati un program initializeaza o lista liniara si executa operatiile specifice asupra listei
(testare daca lista este vida, adaugare, afisare elemente, cautare element, stergere).

2. Realizati un program care evalueaza expresii aritmetice in prefixate. Elementele din expresie vor
fi preluate dintr-un fisier

S-ar putea să vă placă și