Top Banner

of 23

Ministerul Educaţiei Şi Cercetării

Nov 04, 2015

Download

Documents

CiprianCazacu

da
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript

MINISTERUL EDUCAIEI NAIONALELICEUL TEORETIC DUNREA GALAI

PROFESOR NDRUMTOR: NUME:

BIBICU DORIN Moraru Florin

CLASA A XII-A D CUPRINS

4INTRODUCERE N LISTE

7LISTE CIRCULARE

7Introducere

8Clasificarea listelor circulare

11Operaii n liste circulare

14APLICAII

14Reinei coordonatele unui poligon i calculai perimetrul acestuia

16Concatenarea a dou liste circulare

19Se citesc mai multe numere memorate ntr-o list circular.Sfritul listei este marcat prin citirea unei valori egal cu suma ultimelor dou numere introduse.S se realizeze un subprogram recursiv pentru afiarea elementelor n ordinea invers introducerii

23BIBLIOGRAFIE

MOTIVAIA ALEGERII TEMEI

Am ales aceast tem datorit faptului c voi susine examenul de bacalaureat la disciplina informatic, iar capitolul Liste circulare este parte component a programei pentru examenul de bacalaureat.Pe de alta parte, am considerat c modul de abordare dinamic al listelor este destul de dificil i cred c poate fi folosit ca baz in stiudiul informaticii pentru orice elev de nivelul claselor X XI.

INTRODUCERE N LISTE

Lista este o structur de date logic, liniar, cu date omogene, n care fiecare element are un succesor i un predecesor, exceptnd primul element, care nu are dect un succesor, i ultimul element, care nu are dect predecesor.

Unde:

a1 este primul element ( nu are predecesor );

ai este elementul care l are ca succesor pe ai+1 i ca predecesor pe ai-1; an este ultimul element ( nu are succesor );

Operaiile care se pot executa asupra listelor sunt:

iniializarea listei: se creeaz lista vid;

crearea listei: se adaug repetat elemente la list, pornind de la lista vid;

inserarea unui element n list: la nceput, la sfrit, n interior;

tergerea unui element din list: la nceput, la sfrit, n interior;

parcurgerea listei: se viziteaz elementele listei pentru a obine informaii;

cutarea n list a unui element care ndeplinete anumite condiii;

concatenarea a dou liste;

divizarea n dou liste;

n funcie de modul n care se aloc memoria intern, listele pot fi implementate prin dou metode:

metoda static: folosind vectori;

metoda dinamic: folosind pointeri;

n funcie de modul n care sunt aranjate elementele n list, acestea pot fi implementate prin:

metoda secvenial;

metoda nlnuit;

n implementarea prin alocare secvenial nodurile listei sunt stocate ntr-un bloc contiguu de locaii de memorie cu adrese consecutive.De exemplu, dac avem o list format din cuvinte de maximum 4 caractere, acestea vor fi scrise ntr-un bloc contiguu de locaii de 5 octei.Aceast implementare este cea mai simpl i se face folosind un vector de iruri de caractere:

typedef char nod[5];

nod lista[100];

n implementarea prin alocare nlnuit nodurile listei nu mai sunt stocate succesiv n memorie.Aceast implementare se poate face att static, ct i dinamic, ntre cele dou implementri existnd urmtoarele diferene: n implementarea static, nodurile listei ocup un bloc contiguu de locaii de memorie ( zona de memorie alocat vectorului ); n implementarea dinamic, nodurile listei ocup locaii dispersate din memorie ( a cror adres poate fi pstrat cu ajutorul pointerilor );Clasificarea listelor:

Listele liniare se clasific n:

Liste generale: Nu exist restricii pentru operaiile de inserare i tergere a elementelor din list ( se pot face n orice poziie a listei );

Liste restrictive: Exist restricii pentru operaiile de inserare i stergere a elementelor din list ( se pot face numai la extremiti );

LISTE CIRCULARE

IntroducereO list circular simplu nlntuit este o list liniar simplu nlntuit modificat astfel nct ultimul element pointeaz ( direcioneaz ) spre primul element din list.

O list circular dublu nlntuit este o list liniar dublu nlntuit modificat astfel nct ultimele elemente pointeaz respectiv spre primele elemente din list.

n continuare ne vom referi la liste circulare simplu nlntuite pe care le vom numi simplu: liste circulare.

Deci fiecare element din lista circular are urmtoarea structur:

Forma general a unui element dintr-o list circular este:

struct nume_structura {

nume_tip1 nume_var1;

//...................

nume_tipN nume_varN;

nume_structura *nume_pointer; // pointer de tip nume_structura care va indica spre urmatorul element }; Exemplu de element dintr-o list circular este:

struct record

{

int number;

record *next;

};

La listele circulare, pe baza informatiei de nlntuire trebuie s poat fi identificat urmtorul element din list.

Clasificarea listelor circulare

Liste circulare alocate static: Dac implementarea structurii de list circular se face prin tablouri, o list circular este numit list circular alocat static sau simplu o list circular static.

Considerm urmtoarele declaratii:

struct element {

char* data;

int leg;

};

element v[8];

Pentru elementele vectorului V exist o ordine natural dat de aranjarea n memorie a elemetelor sale: v[0], v[1], ...v[7]. Vom reperezenta memoria ocupat de vectorul V astfel nct fiecare element s fie reprezentat vertical, n felul urmtor:

reprezint pentru fiecare element al vectorului legtura catre urmtorul element , iar pentru ca lista s fie circular de la ultimul element se face legatura catre primul.

Observaie: Nu mai exist un ultim element n list ca la listele liniare! Este necesar s cunoastem care este primul element din nlntuire, pentru aceasta retinem ntr-o variabil:

int cap;

Indexul primului element

cap=3;

Parcurgerea n ordine a elementelor listei circulare se face n felul urmtor:

int crt;

.................

if (cap!=null){

crt = cap;

Prelucreaz V[crt]

while (V[crt].leg!=cap) {

crt = V[crt].leg;

Prelucreaza V[crt]

}

}

Liste circulare alocate dinamic:

Dac implementarea structurii de list circular se face prin tehnici de alocare dinamic se obtine o list circular alocat dinamic sau simplu o list circular dinamic.

Considerm urmtoarele declaraii:

struct Element

{

TipOarecare data; // informatia util

Element* leg; // legtura

};

Avnd declaratiile de mai sus (una din forme):

Element* p; // un pointer la Element

n urma unei operatii:

p = (Element*) malloc( sizeof(Element) )Operaii n liste circulare

Parcurgerea listei:

Considerm: cap - contine adresa primului element din list.

O parcurgere nseamn prelucrarea pe rnd a tuturor elementelor listei, n ordinea n care acestea apar n list. Vom avea o variabil pointer p care va indica pe rnd fiecare element al listei:

if (cap!=0){

p = cap;

Prelucreaz p->data

while (p->leg!=cap){

p = p->leg;

Prelucreaz p->data

}

}

Un caz special apare atunci cnd dorim s facem o parcurgere care s se opreasc n fata unui element care s ndeplineasc o conditie (ca n cazul cnd inserm un element ntr-o pozitie dat printr-o conditie, sau stergem un element care ndeplineste o conditie). Presupunem c lista are cel putin un element.

p = cap;

while (p->leg!=cap && !conditie(p->leg))

p = p->leg;

Bucla while se poate opri pe condiia "p->leg==cap", ceea ce nsemn c nici un element din list nu ndeplineste conditia iar pointerul p indic ultimul element din list, sau pe conditia "conditie(p->leg)" , ceea ce nsemn c pointerul p va contine adresa elementului din fata primului element care ndeplineste condiia. Inserarea unui nod n list:

Se pun urmtoarele probleme:

inserarea naintea unui nod de cheie dat;

inserarea dup un nod de cheie dat;

n ambele cazuri se caut nodul de cheie dat avnd adresa q; dac exist un astfel de nod, se creeaz nodul de inserat de adres p i se fac legturile corespunztoare.

Inserarea naintea unui nod de cheie dat:

TIP_NOD *p,*q,*q1;

q = ptr_nod;

do

{

q1 = q; q = q -> urm;

if (q -> cheie = =key ) breaak;

}

while (q! = ptr_nod);

if (q -> cheie == key) {

q1 -> urm = p; p -> urm = q;

}

Inserarea dup un nod de cheie dat:

TIP_NOD *p,*q;

q = ptr_nod;

do

{

if (q -> cheie == key ) break;

q = q -> urm;

}

while(q!=ptr_nod);if (q -> cheie == key)

{

p -> urm =q -> urm;

q -> urm = p;

}

tergerea unui nod din list:

q = ptr_nod;

do

{

q1 = q; q = q -> urm;

if (q -> cheie == key ) break;

}

while (q! = ptr_nod);

if (q-> cheie == key)

{

if (q==q -> urm) ptr_nod==0;

else

{

q1 -> urm = q -> urm;

if (q == ptr_nod) ptr_nod = q1;

}

elib_nod(q);

}

tergerea listei:

p = ptr_nod;

do

{

p1 =p; p = p -> urm;

elib_nod(p1);

}

while (p! = ptr_nod);

ptr_nod = 0;

APLICAII

Reinei coordonatele unui poligon i calculai perimetrul acestuia#include

#include

#include

#include

struct nod

{ int x,y;

struct nod *next;

}*l,*q;

int n,i;

float p;

struct nod* creare()

{ struct nod* aux;int x,y;

l=NULL;

for(i=n;i>=1;i--)

{ aux= (struct nod* )malloc(sizeof(struct nod));

printf("coordonatele vfului %d",i);

printf("x=" );

scanf("%d",&x);

printf("y=" );

scanf("%d",&y);

aux->x=x;

aux->y=y;

aux->next=l;

if (i==n) q=aux;

l=aux;

}

q->next=l;

return l;

}

void afisare()

{ struct nod* c;

c=l;

printf("(%d,%d)",c->x,c->y);

c=l->next;

while(c!=l)

{ printf("(%d,%d)",c->x,c->y);

c=c->next;

}

}

void perimetru()

{ struct nod*c;

c=l;

p=0;

for(i=1;ix-c->next->x,2)+pow(c->y-c->next->y,2),0.5);

c=c->next;

}

}

void main(void)

{ clrscr();

printf("nr de varfuri este " );

scanf("%d",&n);

l=creare();

afisare();

perimetru();

printf("p=%f",p);

getch();

}

Concatenarea a dou liste circulare

#include

#include

#include

struct nod

{ int x;

struct nod *next;

}*l,*l1,*u,*u1,*ultim;

int i,n;

struct nod* creare(struct nod *l, int k)

{struct nod*aux;

int v;

printf("nr de noduri=" );

scanf("%d",&n);

l=NULL;

ultim=NULL;

for (i=n;i>=1;i--)

{

aux= (struct nod*)malloc(sizeof(struct nod));

printf("\nInfo. nodului %d = ",i);

scanf("%d",&v);

aux->x=v;

aux->next=l;

if (i==n) ultim=aux;

l=aux;

}

u->next=l;

if(k==0) u=ultim;

else u1=ultim;

return l;

}

void afisare(struct nod*l)

{ struct nod*c;

c=l;

printf("\n" );

printf("%d ",l->x);

c=l->next;

while (c!=l)

{

printf("%d ",c->x);

c=c->next;

}

}

struct nod* concat(struct nod* l,struct nod* l1)

{ struct nod* c,*aux;

u->next=l1;

u1->next=l;

return l;

}

void main()

{ clrscr();

l=creare(l,0);

afisare(l);

l1=creare(l1,1);

afisare(l1);

printf("\nListele concatenate\n" );

l=concat(l,l1);

afisare(l);

getch();

}

Se citesc mai multe numere memorate ntr-o list circular.Sfritul listei este marcat prin citirea unei valori egal cu suma ultimelor dou numere introduse.S se realizeze un subprogram recursiv pentru afiarea elementelor n ordinea invers introducerii#include

#include

#include

struct nod

{ int x;

struct nod *next;

}*l,*q,*linv,*qinv;

int i,n,start,stop;

struct nod* insert(int x){

struct nod*aux;

aux= (struct nod*) malloc (sizeof(struct nod));

aux->x=x;

aux->next=l;

if (start) q=aux;

l=aux;

return l;

}

struct nod* creare()

{ int v1,v2,v3;

l=NULL;start=1;

printf("Info.= " );

scanf("%d",&v1);

l=insert(v1);

start=0;

stop=0;

printf("Info.= ") ;

scanf("%d",&v2);

l=insert(v2);

printf("Info.= " );

scanf("%d",&v3);

while(stop==0){

if(v3==v1+v2) stop=1;

l=insert(v3);

v1=v2;

v2=v3;

printf("Info.= " );

scanf("%d",&v3);

}

q->next=l;

return l;

}

void afisare(struct nod*l)

{ struct nod*c;

c=l;

printf("%d ",c->x);

c=l->next;

while (c!=l)

{ printf("%d ",c->x);

c=c->next;

}

printf("\n" );

}

struct nod* inversa(struct nod* l)

{ struct nod*aux,*q,*c;

int v;

if(l==NULL) linv=NULL;

else{

linv=insert(l->x);

qinv=linv;

for(c=l->next;c!=l;c=c->next)

linv=insert(c->x);

qinv->next=linv;

}

return linv;

}

0void main()

{ l=creare();

afisare(l);

linv=inversa(l);

afisare(linv);

getch();

}

BIBLIOGRAFIE

Manual informatic clasa a XI-a.Editura LS Soft.Autori: Vlad Huanu, Tudor Sorin;

Programarea modern n C++.Editura Teora.Autor: Andrei Alexandrescu;

http://www.cs.uregina.ca/Dept/manuals/Manuals/7Language/7_18C++/c++.htm Secrete de programare in Windows 98.Editura ZY.Autor: Clayton Walnum;

file://localhost/D:/download/Liste%20dublu%20inlantuite,%20liste%20circulare.htm http://www.skullbox.info/board/-curs-c-lectia-12-liste-p31092.html http://cppcorner.3x.ro/circularlist.htmlan

ai+1

ai

ai-1

a2

a1

Liste generale

Coada

Operaia de introducere a elementelor se face pe la o extremitate, iar extragerea prin cealalta extremitate

Stiva

Operaiile de introducere i extragere a elementelor se pot face numai printr-una din extremiti

Liste restrictive

Lista simplu nlnuit:

Fiecare element pstreaz legtura cu un singur vecin

Lista dublu nlnuit:

Fiecare element pstreaz legtura cu ambii vecini

Lista circular:

Este o list nlnuit n care elementul ultim se leaga de cel prim

a1

ai+1

ai

ai-1

a2

a1

an

v[1]

v[7]

v[6]

v[4]

v[3]

v[2]

v[1]

Pagina 23