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