Sunteți pe pagina 1din 15

PA

//ALGORITM

Algoritm= metoda generala de rezolvare a unui tip de problema metoda implementata pe


calculator prin intermediul unui program.Este alcatuit dintr-un numar de pasi a caror executie
trebuie sa se realizeze intr-un timp rezonabil

Caracteristici algorim:

- generalitatea( un algoritm rezolva un set de probleme de acelasi tip nu doar una singura)
- unicitatea( un algoritm rezolva aceasi set de probleme indifernet de limbajul de programare
in care este implementat)
- finititudinea( solutia problemei trebuie identificata intr-un timp rezonabil cea ce presupune
ca algoritmul poseda un numar finit de pasi)

Etape proiectare algoritm:

1. elaborarea algoritmului
2. exprimarea algoritmului(trebuie sa fie clar si concis exprimat intr-un limbaj de programare)
3. validarea algoritmului(este corect daca furnizeaza solutia corecta ptr orice set de date de
test)
4. testarea algoritumului care este formata din 2 etape: debugging(depanare) si
profiling(trasare)

debugging=corectarea de erori ale algoritmului

profiling=determinarea timpului de calcul si a memoriei utilizare

Metode de proiectare a algoritmilor:

1. recursivitatea(presupune elaborarea si utilizarea functiilor recursive)


2. Greedy(metoda lacoma) se aplica ptr problemele de utilizare
3. Divide et Impera
4. Backtracking se aplica problemelor a caror solutie se pot scrie sub forma de vector
5. Branch and Bound este o combinatie dintre Divide et Impera si ideea de optimizare

//RECURSIVITATE:

->metoda principala de proiectare a algoritmilor

Este o metoda de proiectare a algoritmilor care permite construirea si utilizare functiilor care se auto
apeleaza
Auto-apel = ce se intampla la un nivel al functiei are lor si in nivelele urmatoare dar pentru alte valori
ale parametrilor

Recursivitatea presupune lucrul cu 2 tipuri de functii:

1) functii recursive directe

Functia recursiva directa este o functie care se auto-apeleaza sau care constituie o referinta
la ea insasi

ex:

factorial(n)=n*factorial(n-1);
Fibonacci(n)=Fibonacci(n-1)+Fibonacci(n-2);

2) functii recursive indirecte

Este o functie care se autoapeleaza prin intermediul altei functii

ex: Functia X contine o referinta la o functie Y iar la randul ei functia Y contine o referinta la
functia X

Daca o problema admite rezolvare recursiva atunci sigur exista cel putin o varianta de rezolvare
iterativa a problemei

Orice functie recursiva trebuie sa contina o conditie de oprire care sa permita iesirea din auto-apel
altfel functia se va auto-apela la infinit

Mecanismul recursivitatii utilizeaza stiva program.La momentul auto-apelului in stiva program se


depun:

-val parametrilor transmisi prin valoare

-val parmaetrilor transmisi prin referinta

-adresele variabilelor locale

//ALOCAREA MEMORIEI

A aloca memorie pentru o variabila inseamna a asocia o zona de memorie pentru variabila
respectiva

Alocarea memoriei poate fi:


-alocare statica/directa

-alocare dinamica/indirecta

Alocarea statica/directa presupune lucrul cu tablouri unidimensionale(vectori) si


bidimensionale(matrici)

-in timpul alocarii statice asocierea dintre nume variabila si zona de memorie este constanta pe
toata durata executiei programului

-presupune cunoasterea valori curente a variabilei memorate de la inceputul executiei programului


pan la sfarsitul acesteia

-variabila alocata static ocupa spatiul de memorie chiar daca aceasta la un moment dat devine
inutila deoarece nu se pot face dealocari de memorie

Alocarea dinamica/indirecta

-in cazul alocari dinamice de memorie asocierea nume de variablia zi zona de memorie nu mai este
constanta pe toata durata executiei programului

-presupune lucrul cu pointeri ( sunt singurele tipuri de date ce permit alocari/dealocari de memorie
in momentul executiei programului)

ex pointer: int *x;

float* v[50];

Forma generala de declarare a unui pointer: tip*nume_pointer;

Alocarea spatiului de memorie in cazul alocarii dinamice se face utilizind functia malloc()

Eliberarea spatiului de memorie se face folosind diferite versiuni ale functiei free()

Functiile mlloc() si free() se gasesc in alloc.h


Tipuri de date:

1)vectori/matrici

2)uniuni,structuri,enumerari

3)liste alocate dinamic (lista s inlantuita,lista d inlantuita,lista circulara,stiva,coada)

4)arbori(oarecare,binari,de cautare)

5)grafuri(orientate/neorientate)

//STRUCTURA

Este o colectie de date neomogena stocate intr-o zona de memorie compacta sub acelasi nume

Daca variabilele din lista de structuri sunt alocate static accesul se face folosind un punct .

nume_var . nume_camp;

Daca variabilele din lista de structuri sunt alocate dinamic accesul se face folosind o sageata ->

nume_var -> nume_camp;

struct student

{struct nume[10],pren[10];

int varsta;

}stud1;

Declaratia typedef are rolul de a redenumi un tip de date deja existent

//UNIUNEA

Este un tip de date structurat in care campuri diferite utilizeaza aceasi zona de memorie la momente
diferite de timp

union struct

{char nume[10],pren[10];

int varsta;

}e;
//ENUMERAREA

Este o lista de constante ce pot fi atribuite unei variabile

enum luna_an

{ianuaria,februarie,martie,...decembrie

}luna;

Functii pentru lucrul cu siruri de caractere:

1) in stdio.h avem
printf()
scanf()
gets()
puts()

2) in string.h avem
strcmp(sir1,sir2) =>compara lexicografic sir 1 cu 2
strcopy(sir1,sir2)=>copieaza sir 2 in 1
strlen(sir)=> intoarce lungime sir
strcat(sir1,sir2)=>lipeste/concanteneaza sir 1 de 2

//STIVA

Este un caz particular de lista simplu inlantuita. Operatiile de adaugare si de stergere a elementelor
se realizeaza pe la un singur cap ( varful stivei)

Principiul de functionare este LIFO ( Last In First Out)

//Declarere Stiva :
typedef struct lista
{
int inf;
struct lista* leg;
}stiva;

//Initiere Stiva :
stiva * initiere(stiva* l)
{
l = NULL;
return l;
}
//Creare Stiva :
stiva * creare(stiva* l, int info)
{
stiva* a;
a = (stiva*)malloc(sizeof(stiva));
a->inf = info;
a->leg = l;
l = a;
return l;
}

//Afisare Stiva :
void * afisare(stiva* l)
{
stiva* aux{};
cout << aux->inf;
aux = aux->leg;
}

//Eliminarea primului element


stiva* eliminare_prim_element(stiva* l)
{
stiva* aux;
aux = l;
l = l->leg;
free(aux);
return l;
}

//Eliminarea ultimului element


stiva* eliminare_ultim_element(stiva* l)
{
stiva* aux;
aux = l;
while (aux->leg->leg != NULL)
{
aux = aux->leg;
free(aux->leg);
aux->leg = NULL;
return l;
}
}

//Adaugare element
stiva* adaugare(stiva * l, int info1)
{
stiva* w, * aux;
w = (stiva*)malloc(sizeof(stiva));
w->inf = info1;
while (aux->leg != NULL)
{
aux = aux->leg;
aux->leg = w;
w->leg = NULL;
return l;
}

}
//COADA

Este un caz particular al unei liste simplu inlantuita.Operatia de adaugare a elementelor in coada se
face pe la un capat al cozii (finalul) iar operatia de stergere a elemntelor se realizeaza prin celalalt
capat al cozii (inceputul)

Functioneaza dupa principul FIFO (First In First Out)

//Initializare coada :
typedef struct lista
{
int inf;
struct lista* leg;
}coada;

//Creare coada :
coada * creare()
{
coada* prim, * ultim, * a, int info;
prim = NULL;
ultim = NULL;
cout << "Info: ";
cin >> info;
while (info != 0)
{
a = (coada*)malloc(sizeof(coada));
a->inf = info;
a->leg = NULL;
if (prim == NULL)
{
prim = a;
ultim = a;
}
else
{
ultim->leg = a;
ultim = a;
}
cout <<"Info: ";
cin >> info;
}
return prim;

//Parcurgere coada :
void* parcurgere(coada* prim)
{
coada* aux;
if (prim != NULL)
{
aux = prim;
while (aux != NULL)
{
cout << aux->leg;
aux = aux->leg;
}
}
}
//Stergere prim element coada :
coada* stergere_prim(coada * prim)
{
coada* aux;
aux = prim;
prim = prim->leg;
free(aux);
return prim;
}

//Adaugare elemente la final coada:


coada* adaugare_final(coada* prim, int info)
{
coada* aux, * a;
a = (coada*)malloc(sizeof(coada));
a->inf = info;
aux = prim;
while (aux->leg != NULL)
{
aux = aux->leg;
aux->leg = a;
a->leg = NULL;
return prim;
}
}

//ARBORI OARECARE/BINARI

Un arbore oarecare este o sturctura de date ierarhica in care ficare nod poate acea unul sau mai
multi fii. Nu exista restrictii asupra numarului de fii in cazul unui arbore oarecare

Un arbore binar este o structura de date ierarhica in care fiecare nod poate avea cel mult 2 fii: unul
stang si unul drept

Notiuni arbori:

nod radacina = primul nod al unui arbore

subarbori = restul nodurilor ce formeaza un arbore

nod parinte/tata = nod ce prezinta fii adica descendentii directi


ascendent = nod de pe un rand superior al unui nod

descendent = nod de pe un rand inferior al unui nod

noduri frati = noduri care au acelasi ascendent (nod tata)

nod frunza = nodurile terminale care nu au decendenti

nod interior = nod terminal care are descendeti

grad nod = numarul de descendenti directi ai nodului

<--- arbore pefect echilibrat

<------ arbore echilibrat


//Declarare arbore oarecare :
typedef struct arbore
{
int inf;
int nr_fii;
struct arbore* adrese_fii[10];
}arb_oarecare;

//Creare arbore oarecare :


arb_oarecare* creare()
{
int info;
arb_oarecare* a;
a = (arb_oarecare*)malloc(sizeof(arb_oarecare));
cout << "Info nod: ";
cin >> info;
a->inf = info;
cout << "Numar fii pentru nodul cu informatia " << info << " este: ";
cin >> a->nr_fii;
for (int i = 1; i <= a->nr_fii; i++)
{
a->adrese_fii[i] = creare();
return a;
}
}
Parcurgerea unui arbore oarecare este de mai multe tipuri:

-in adancime : preordine/prefixata (RSD – radacina stanga dreapta)

postordine/postfixata (SDR – stanga dreapta radacina)

-in latime: (se parcurg in ordine nodurile de pe fiecare nivel de la stanga la dreapta ,incepand de la
primul nivel pana la ultimul)
//Parcurgerea in preordine(RSD) :
void RSD(arb_oarecare* t)
{
if (t != NULL)
{
cout << t->int << ”, ”;
for (int i = 1; i <= t->nr_fii; i++)
{
RSD(t->adrese_fii[i];
}

//Parcurgere in postordine(SDR) :
void SDR(arb_oarecare * t)
{
if (t != NULL)
{
for (int i = 1; i <= t->nr_fii; i++)
{
SDR(t->adrese_fii[i]);
cout << t->inf << ”, ”;
}
}
}

//Declarare arobore binar :


typedef struct arbore
{
int inf;
struct arbore* st, * dr;
}arbbin;

//Creare arbore binar :


arbbin* creare()
{
int info;
arbbin* a;
cout << ”Introdu info : ”;
cin >> info;
if (info != 0)
{
a = (arbbin*)malloc(sizeof(arbbin);
a->inf = info;
a->st = creare();
a->dr = creare();
return a;
}
else return NULL;
}
//Parcurgere arbore binar :

//in preordine RSD :

void RSD(arbbin * t)
{
if (t != NULL)
{
cout << t->inf;
RSD(t->st);
RSD(t->dr);
}
}

//in postordine SDR

void SDR(arbbin * t)
{
if (t != NULL)
{
SDR(t->st);
SDR(t->dr);
{cout << t->inf;
}
}

//parcurgere stanga radacina dreapta

void SRD(arbbin * t)
{
if (t != NULL)
{
SRD(t->st)
cout << t->inf;
SRD(t->dr);
}
}

//ARBORE BINAR DE CAUTARE (BST - BINARY SEARCH TREE)

BST-ul este un arbore binar in care pentru fiecare nod toate valorile din subarborele stang sunt mai
mici decat valoarea nodului isr toate valorile din subarborele drept sun mai mari sau egale cu
valoarea nodului. Aceasta proprietate face ca operatiile de cautare inserare si stergere sa fie
eficiente

//Declarare BST
typedef struct arbore
{
int inf;
struct arbore* st, * dr;
}arbbin_cautare;
//Creare BST
void inserare_nod(Search_BTree*& a, intcheie_nod)
{
Search_BTree* nod;
if (a != NULL)
if (cheie_nod == a - →inf)
cout << "\n Nodul exista deja in BST!";
else if (a→inf < cheie_nod)
inserare_nod(a→dr, cheie_nod);
else inserare_nod(a→st, cheie_nod);
else if (a == NULL)
{
nod = (Search_BTree*)malloc(sizeof(Search_BTree));
nod→inf = cheie_nod;
nod→st = NULL;
nod→dr = NULL;
a = nod;
}
}

//Parcurgere BST :

//in preordine RSD(radacina stanga dreapta)

void RSD(Search_BTree* t)
{
if (t != NULL)
{
cout << t->inf << ”, ”;
RSD(t->st);
RSD(t->dr);
}
}

//in postordine SDR(stanga dreapta radacina)

void SDR(Search_BTree* t)
{
if (t != NULL)
{
SDR(t->st);
SDR(t->dr);
cout << t->inf << ”, ”;

in latime SRD(stanga radacina dreapta_

void SRD(Search_BTree * t)
{
if (t != NULL)
SRD(t->st);
cout << t->inf << ”, ”;
SRD(t->dr);
{
}
}
//Stergere Nod BST :
void sterg_nod_terminal(Search_ BT ree * &nod, int info)
{
Search_BTree* aux;
if (nod != NULL)
{
if (nod→inf == info)
{
if ((nod→st == 0) && (nod - →dr == 0))
{
delete nod;
nod = 0;
}
}
else if (nod→inf < info)
sterg_nod_terminal(nod→dr, info);
else sterg_nod_terminal(nod→st, info);
}
}

GRAF

Este o structura matematica formata dintr-un set de noduri/varfuri si un set de muchii/arce care
conecteaza perechi de noduri.

Grafurile sunt:

-neorientate (sunt un tip de graf in care muchiile nu au o directie specifica, ele conecteaza 2 noduri si
pot fi tranversate in ambele directii)

-orientate ( sunt un tip de graf in care muchiile au o directie specifica, ele conecteaza un nod sursa la
un nod destinatie si nu pot fi traversate in directie inversa fara a schimba directia muchiei

GRAF NEORIENTAT GRAF ORIENTAT


muchie arc
lant drum
arc circuit
grad nod grad interior(Gi) /exterior(Ge) nod
graf conex graf tare conex

PTR UN GRAF NEORIENTAT:

-Un lant intr-un graf neorientat este o secventa de noduri conectate prin muchii a.i. fiecare nod este
conectat direct cu nodul urmator in secventa.Niciun nod nu apare de mai multe ori in lant

-Un ciclu intr-un graf neorientat este un lant in care primul si ultimul nod sunt identice a.i. se
formeaza o bucla in graf

-Un graf neorientat este conex daca exista un drum intre oricare pereche de noduri din graf
- Un graf complet este un graf neorientat in care fiecare pereche distincta de noduri este conectata
printr-o muchie

-Gradul unui nod intr-un graf neorientat reprezinta numarul de muchii incidente cu acel nod ( nr de
vecini ai nodului respectiv)

-Grafurile neorientate se reprez in mermoria calculatorului prin: Matricea de Adiacenta sau Lista de
Adiacenta

PTR UN GRAF ORIENTAT:

-Un drum intr-un graf orientat este o secventa de noduri conectate prin muchii a.i. fiecare nod este
conectat direct cu nodul urmator in secventa.Nodurile pot aparea de mai multe ori in drum

-Un circuit intr-un graf orientat este un drum in care primul si ultimul nod sunt identice a.i. se
formeaza un ciclu in graf

-Un graf orientat este tare conex daca exista un drum orientat intre orice pereche de noduri din graf

-Intr-un graf orientat gradul interior al unui nod reprez nr de muchii care intra in acel nod iar gradul
exterior al unui nod reprez nr de muchii care ies din nod

-Grafurile orientate se reprez in mermoria calculatorului prin: Matricea de Adiacenta sau Lista de
Adiacenta

Modalitati de parcurgere a unui graf:

-in latime BFS ( Breadth First Search) consta in explorarea nodurilor in ordinea nivelului lor in raport
cu nodul de start. Se incepe de la nodul start se viziteaza vecini sai apoi se trece la vizitarea vecinii
vecinilor si asa mai departe pana sunt vizitate toate nodurile sau se atinge scopul

-in adancime DFS (Depth First Search) consta in explorarea cat mai adanc posibila a unui lant si apoi
revenirea la alt lant neexplorat. Se incepe de la nodul start se exploreaza un vecin neizitat apoi se
exploreaza vecinii nevizitati ai acestui vecin si asa mai departe pana cand nu mai exista vecini
nevizitati sau se atinge un anumit scop

Algoritmi:

Roy-Warshall ( algoritm ptr determinarea matricei drumurilor)

Roy-Floyd ( algoritm ptr determinarea matricei drumurilor de cost minim)

Dijkstra ( algoritm ptr gasirea celui mai scurt drum intre un nod de start si toate celelalte noduri din
graf se foloseste o strategie Greedy)

Prim/Kruskal (algoritm ptr determinarea arborelui de cost minim asociat unui graf)
Metode de sortare:

-sortare prin interschimbare ( BUBBLE SORT)

consta in compararea si interschimbarea repetata a perechilor de elemente adiacente pana cand


sirul este complet sortat

-sortare prin insertie ( INSERTION SORT)

funcționează prin inserarea fiecărui element dintr-o listă nesortată în locul corespunzător într-o
sublistă sortată. În fiecare pas, se alege un element din lista nesortată și se plasează în locul său
corect în lista sortată. Acest proces se repetă până când toate elementele sunt sortate

-sortare prin selectie ( SELECTION SORT)

funcționează prin selectarea celui mai mic element din lista nesortată și plasarea lui în partea sortată
a listei. Acest proces se repetă pentru fiecare element din lista nesortată până când întreaga listă
este sortată

-sortare prin interclasare ( MERGE SORT)

funcționează prin împărțirea listei inițiale în două subliste egale sau aproximativ egale, sortarea
acestor subliste, apoi combinarea sublistelor sortate într-o singură listă sortată.

-sortare rapida ( QUICK SORT)

funcționează prin alegerea unui element din lista de sortat, numit element pivot, și împărțirea listei
în două subliste: una cu elemente mai mici sau egale cu pivotul și cealaltă cu elemente mai mari sau
egale cu pivotul. Apoi, cele două subliste sunt sortate recursiv

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