Sunteți pe pagina 1din 11

TABLOURI UNIDIMENSIONALE (SIRURI, VECTORI)

n cazul n care o aplicaie trebuie s prelucreze un ir de 20 de numere, s le ordoneze


cresctor de exemplu, numerele sunt date de intrare pentru algoritm i n primul pas vor fi introduse
n memoria calculatorului.
La pasul urmtor numerele vor fi prelucrate i aranjate conform criteriului de ordonare
precizat, dup care, la al treilea pas, vor fi furnizate utilizatorului sub form de date de ieire. n
memoria intern ele vor fi reprezentate ntr-o structura de date de tip tablou de memorie.
Tabloul este o structur de date intern format dint-o mulime ordonat de elemente,
ordonarea fcndu-se cu un ansamblu de indici. Tabloul de memorie se va identifica dup un nume,
iar fiecare element al su, dup numele tabloului i numrul su de ordine. Fiecare element al
structurii se identific dup numele tabloului i poziia din tablou. De la nceput trebuie s se
precizeze cte elemente are tabloul pentru ca sistemul s-i aloce zona de memorie corespunztoare.
n timpul prelucrrii tabloului nu i se pot aduga mai multe elemente dect au fost alocate, pentru c
se iese din spaiul de memorie alocat. Tabloul de memorie este o structur de date static.
Tabloul cu o singur dimensiune este numit vector.

Declararea unui tablou de memorie de tip vector se face prin instructiunea:


Tip_data nume [ nr_elemente ];
Aici, tip_data precizeaz tipul elementelor vectorului, nume este identificatorul vectorului, iar
nr_elemente este o constant ntreag care specific numrul de elemente ale vectorului. De exemplu,
prin:
int a[20]; se declar un vector cu 20 de elemente de tip ntreg.
La declararea unui vector se pot atribui valori iniiale elementelor sale astfel:

Tip_data nume[ nr_elemente ] = { lista_valori };


Exemplu:
int a[5]={10, 20, 2, 4, 9 };
n cazul declarrii unui vector iniializat se poate omite numrul elementelor sale, dac se
iniializeaz toate elementele.
Referirea la un element al vectorului se face prin construcia:

nume[indice];
unde nume este numele tabloului, iar indice este numrul de ordine al elementului n vector. n C++
numerotarea indicilor se face pornind de la 0!

1
CUTARE SECVENIAL
Cutarea secvenial este unul dintre cei mai simpli algoritmi studiai. El urmrete s verifice
apartenena unui element la un ir de elemente de aceeai natur, n spe a unui numr la un ir de
numere. Pentru aceasta se parcurge irul de la un capt la cellalt i se compar numrul de cutat cu
fiecare numr din ir. n cazul n care s-a gsit coresponden (egalitate), un indicator flag este
poziionat. La sfritul parcurgerii
irului, indicatorul ne va arta dac numrul cutat aparine sau nu irului.
#include<iostream>
using namespace std;
int main()
{
int n,x,i,gasit,a[50];
cout<<"Dati numarul de elemente ale sirului : "; cin>>n;
cout<<"Dati numarul de cautat : "; cin>>x;
cout<<"Dati elementele sirului"<<endl;
gasit=0;
for(i=0; i<n; i++){
cout<<"a["<<i<<"]= "; cin>>a[i];
if (a[i]==x) gasit=1;
}
if (gasit==0)
cout<<"Numarul nu apartine sirului !"<<endl;
else cout<<"Numarul apartine sirului !"<<endl;
}

Tem.
S se transforme programul anterior astfel nct s se afieze poziiile n care apare elementul
cutat.

CUTARE BINAR

2
Algoritmul de cutare binar ofer performane mai bune dect algoritmul de cutare
secvenial. El funcioneaz astfel: se compar numrul de cutat cu elementul aflat la mijlocul
irului (element care se mai numete i pivot). n cazul n care cele dou elemente coincid cutarea s-
a ncheiat cu succes. Dac numrul de cutat este mai mare dect pivotul, se continu cutarea n
aceeai manier n subirul delimitat de pivot i captul irului iniial. Dac numrul de cutat este
mai mic dect pivotul se continu cutarea n aceeai manier n subirul delimitat de pivot i
nceputul irului iniial.
Algoritmul prezentat se ncadreaz n clasa algoritmilor elaborai conform tehnicii de
programare Divide et Impera.
Unul din dezavantajele acestui algoritm este c irul n care se face cutarea trebuie s fie iniial
sortat.

#include<iostream>
using namespace std;
int main()
{
int i, n, x, st, dr, mijl, gasit, a[50];
cout<<"Introduceti numarul elementelor vectorului : ";
cin>>n;
cout<<"Introduceti elementul de cautat : ";
cin>>x;
for(i=0;i<n;i++) {
cout<<"a["<<i<<"]= ";
cin>>a[i];
}
st=0; dr=n-1; gasit=0;
while (st<=dr && gasit!=1) { 3
mijl=(st+dr)/2;
if (a[mijl]==x)
gasit=1;
else
if (x<a[mijl])
dr=mijl-1;
else
st=mijl+1;
}
if (st>dr)
cout<<"Nu s-a gasit elementul cautat !"<<endl;
else
cout<<"Elementul cautat apartine sirului !"<<endl;
}

Problem.

3
S se elaboreze un algoritm pentru tergerea dintr-un vector a elementului cu indicele k i
deplasarea elementelor vectorului, ncepnd cu indicele k+1, cu o poziie spre stnga, lungimea
logic a vectorului micorndu-se cu 1.
#include<iostream>
using namespace std;
int main()
{
int i,n,k,a[10];
cout<<"Introduceti dimensiunea vectorului : "; cin>>n;
cout<<"Introduceti indicele elementului ce se elimina : "; cin>>k;
for(i=0;i<n;i++) {
cout<<"a["<<i<<"]=";
cin>>a[i];
}
for(i=k;i<n-1;i++)
a[i]=a[i+1];
cout<<"Vectorul rezultat este : ";
for(i=0;i<n-1;i++)
cout<<a[i]<<" ";
cout<<endl;
}

4
Problem.
Algoritmul pentru inserarea unui element ntr-un vector n poziia indicelui k nseamn
deplasarea elementelor vectorului, ncepnd cu indicele k+1, cu o poziie spre dreapta i apoi
atribuirea noii valori lementului cu indicele k. Lungimea logic a vectorului se va mri cu o unitate
i va fi n+1, cu condiia ca n+1 s fie mai mic sau cel puin egal cu lungimea fizic a vectorului, altfel
ultimul element al vectorului se pierde.
#include<iostream>
using namespace std;
int main()
{
const int dim=10;
int i,n,k,x,a[dim];
cout<<"Introduceti dimensiunea vectorului (<=10): "; cin>>n;
cout<<"Introduceti pozitia de inserare : "; cin>>k;
cout<<"Introduceti elementul ce se insereaza : "; cin>>x; 4
for(i=0;i<n;i++) { //sunt citite componentele vectorului
cout<<"a["<<i<<"]=";
cin>>a[i];
}
cout<<"Vectorul obtinut prin inserare este : ";
if(n!=dim) {
//daca dimensiunea era strict mai mica decat dim, putem obtine
//un vector de dimensiune mai mare, fara pierderea de elemente
for(i=n;i>k-1;i--)
a[i]=a[i-1];
a[k-1]=x;
for(i=0;i<n+1;i++)
cout<<a[i]<<" ";
}
else {
//prin inserarea elementului x se pierde ultima componenta a
//vectorului citit de la tastatura
//prima ramura din if-ul urmator este pentru situatia in care
//pozitia de inserare nu este ultima pozitie a vectorului initial
if (k<n-1) {
for(i=n-1;i>k-1;i--)
a[i]=a[i-1];
a[k-1]=x;
for(i=0;i<n;i++)
cout<<a[i]<<" ";
}
else {
//cazul in care trebuie inserat un element pe ultima pozitie
//a vectorului initial
a[n-1]=x;
for(i=0;i<n;i++)
cout<<a[i]<<" ";
}
}
cout<<endl; }

5
METODE DE SORTARE PENTRU VECTORI
1. Sortarea prin selecie direct
Considerm un vector de elemente comparabile ntre ele i dorim s le ordonm cresctor. Pentru
aceasta comparm primul element cu toate elementele care urmeaz dup el. Dac gsim un element
mai mic dect primul atunci le interschimbm pe cele dou. Apoi continum cu al doilea element al
irului, pe care, de asemenea l comparm cu toate elementele care urmeaz dup el i n caz de
inversiune interschimbm cele dou elemente. Apoi procedm la fel cu al treilea element al irului
iar procesul continu astfel pna la penultimul element al irului care va fi comparat cu ultimul
element din ir.

#include<iostream>
using namespace std;
int main()
{
int i,j,n,aux,a[50]; 5
cout<<"Introduceti numarul de elemente din sir : ";
cin>>n;
cout<<"Introduceti numerele"<<endl;
for(i=0;i<n;i++) {
cout<<"a["<<i<<"]=";
cin>>a[i];
}
//urmeaza algoritmul de sortare
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if (a[j]<a[i]) {
aux=a[i];
a[i]=a[j];
a[j]=aux;
}
//urmeaza afisarea sirului sortat
cout<<"Sirul sortat este:"<<endl;
for(i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}

6
2. Sortarea prin metoda bulelor
Acest algoritm se mai numete i "sortarea prin selecie i interschimbare", "sortarea prin
propagare" sau "metoda lent de sortare" datorit numrului mare de operaii care trebuie efectuate.
Succesul algoritmului este asigurat de trecerea succesiv prin tablou, pn cnd acesta este sortat, cu
specificaia c, la fiecare trecere, elementele succesive i i i+1 pentru care a[i]>a[i+1], vor fi
interschimbate. Metoda poate fi imbuntit dac, dup fiecare trecere, se va reine ultima poziie
din tablou n care a avut loc o interschimbare, iar trecerea urmtoare se va efectua doar pin la acea
poziie. n cazul n care la o trecere nu a avut loc nici o interschimbare algoritmul se va incheia.
Pentru o i mai bun optimizare se poate nlocui trecerea prin tablou ntr-un sens cu trecerea n
dublu sens. n acest caz, dac la dou treceri succesive, ntre dou elemente i i i+1 nu a avut loc o
interschimbare, atunci nici la trecereile urmtoare nu se vor nregistra interschimbri. Cu toate
optimizrile aduse acestei sortari, ea se dovedete a fi cu mult mai lent dect sortarea prin inserie,
fiind ns preferat de unii datorit simplitii, ce nu ridic probleme de implementare. Pentru valori
suficient de mari ale dimensiunii vectorului ce urmeaz a fi sortat se recomand utilizarea unor
algoritmi ce au o complexitate mai redusa i, prin urmare, ofer un timp de calcul mai mic.
#include<iostream>
using namespace std;
int main()
{
int n,i,aux,terminat,a[50];
cout<<"Introduceti dimensiunea vectorului : ";
cin>>n;
for(i=0;i<=n-1;i++) {
cout<<"a["<<i<<"]="; 6
cin>>a[i];
}
terminat=0;
while(!terminat) {
terminat=1;
for(i=0;i<n-1;i++)
if(a[i]>a[i+1]) {
aux=a[i];
a[i]=a[i+1];
a[i+1]=aux;
terminat=0;
}
}
cout<<"Vectorul ordonat este : ";
for(i=0;i<=n-1;i++)
cout<<a[i]<<" ";
cout<<endl;
}

7
3. Sortarea prin inserie
Sortarea prin inserie se bazeaz pe aceleai principii ca i cele aplicate de majoritatea juctorilor de
cri, adic dup ridicarea unei cri de pe mas, aceasta se aeaz n pachetul din mn la locul
potrivit. Cu alte cuvinte, considerm c avem vectorul sortat a, iar la ivirea unui nou element care se
va aduga vectorului, el va fi pus pe locul potrivit printr-o inserie n interiorul vectorului.
- Inseria direct.
Este cea mai simpl implementare a algoritmului i se face n felul urmtor: Se consider c primele
i elemente al vectorului sunt deja sortate. Pentru elementul al (i+1)-lea, din tabloul iniial, se va gsi
poziia n care trebuie inserat printre primele i elemente. Toate elementele tabloului de la aceast
poziie i pn la i vor fi deplasate cu o poziie mai la dreapta iar poziia eliberat va fi ocupat de
elementul i+1.
- Inserarea rapid.
Deoarece vectorul destinaie este un vector ordonat cresctor, cutarea poziiei n care va fi inserat
a[i] se poate face nu secvenial (ca n cazul inserrii directe) ci prin algoritmul de cutare binar.
Subvectorul destinaie este mprit n doi subvectori, se examineaz relaia de ordine dintre
elementul de la mijlocul subvectorului i elementul a[j] i se stabilete dac elementul a[i] va fi
inserat n prima jumtate sau n a doua jumtate. Operaia de divizare a subvectorului continu pn
se gsete poziia n care urmeaz s fie inserat a[i].

#include<iostream>
using namespace std;
int main()
{
int i,j,n,aux,a[50];
cout<<"Introduceti dimensiunea sirului : "<<endl;
cin>>n;
cout<<"Dati elementele sirului :"<<endl;
for(i=0;i<n;i++) {
cout<<"a["<<i<<"]=";
cin>>a[i];
}
for(j=1;j<n;j++) { 7
aux=a[j];
i=j-1;
while (aux < a[i] && i>=0){
a[i+1]=a[i];
i=i-1;
}
a[i+1]=aux;
}
cout<<"Sirul ordonat este: ";
for(i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}

8
4. Sortarea prin numrare
Aceast metod necesit spaiu suplimentar de memorie. Ea folosete urmtorii vectori:
- vectorul surs (vectorul nesortat) a;
- vectorul destinaie (vectorul sortat) b;
- vectorul numrtor (vectorul de contoare) k.
Elementele vectorului surs a[i] se copie n vectorul destinaie prin inserarea n poziia
corespunztoare, astfel nct, n vectorul destinaie s fie respectat relaia de ordine. Pentru a se
cunoate poziia n care se va insera fiecare element, se parcurge vectorul surs i se numr n
vectorul k, pentru fiecare element a[i], cte elemente au valoarea mai mic dect a lui. Fiecare
element al vectorului k este un contor pentru elementul a[i].
Valoarea contorului k[i] pentru elementul a[i] reprezint cte elemente sunt mai mici decit el i arat
de fapt poziia n care trebuie copiat n vectorul b.
#include<iostream>
using namespace std;
void main()
{
int i,j,n,a[50],b[50],k[50]={0};
cout<<"Introduceti dimensiunea sirului : ";
cin>>n;
for(i=0;i<n;i++) {
cout<<"a["<<i<<"]=";
cin>>a[i];
}
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(a[i]>a[j])
k[i]++;
else k[j]++;
for(i=0;i<n;i++)
b[k[i]]=a[i];
cout<<"Vectorul ordonat este : ";
for(i=0;i<n;i++)
cout<<b[i]<<" ";
cout<<endl;
}

9
Algoritm pentru interclasarea a doi vectori (*)
Interclasarea a doi vectori nseamn reuniunea celor doi vectori simultan cu ordonarea elementelor
vectorului rezultat. Presupunem c cei doi vectori sunt sortai (cresctor sau descresctor). Prin acest
algoritm se parcurg simultan cei doi vectori surs pentru a se compara un element dintr-un vector cu
un element din cellalt vector.
Elementul cu valoarea mai mic, respectiv mai mare, este copiat n vectorul destinaie i ters din
vectorul surs. Procesul continu pn cnd este epuizat unul dintre vectori. Elementele rmase n
cellalt vector se adaug la sfritul vectorului destinaie.
Se folosesc urmtoarele variabile de memorie pentru:
- vectori: a i b - vectorii surs (se presupune c sunt deja sortai cresctor sau descresctor) i c -
vectorul rezultat (vectorul destinaie) care reunete elementele din vectorii a i b, ordonate dup
acelai criteriu ca i cele din vectorii surs;
- lungimile logice ale vectorilor: n - pentru vectorul a (se introduce de la tastatur) i m - pentru
vectorul b (se introduce de la tastatur); lungimea vectorului c va fi n+m;
- contorii pentru parcurgerea vectorilor: i - pentru vectorul a, j - pentru vectorul b si k - pentru
vectorul c.

Pasii algoritmului (pentu vectori sortati crescator) sunt:


Pas 1. Se iniializeaz variabilele contor, pentru vectorii surse i pentru vectorul rezultat, cu 0: i=0,
j=0, k=0.
Pas 2. Se compar elementele a[i] i b[j]. Dac a[i]<b[j] se copie elementul a[i] n vectorul c prin
c[k]=a[i] i se terge elementul a[i] din vectorul a; altfel, se copie elementul b[j] n vectorul c prin
c[k]=b[j] i se terge elementul b[j] din vectorul b. Operaia de tergere nu se execut prin
eliminarea efectiv a elementului din vector, ci prin incrementarea contorului: dace se terge
elementul din vectorul a se incrementeaz contorul i, iar dac se terge elementul din vectorul b se
incrementeaz contorul j.
Pas 3. Se incrementeaz contorul k pentru c urmeaz s se copie un element n acest vector.
Pas 4. Se compar contorii vectorilor surs cu lungimea lor. Dac fiecare contor este mai mic sau
egal cu lungimea vectorului (i<n i j<m) se revine la pasul 2, n caz contrar se trece la pasul urmator.
Pas 5. Se adaug la fritul vectorului c elementele rmase n cellalt, printr-o simpl operaie de
copiere: dac i<n nseamn c s-a epuizat vectorul b i se vor aduga la vectorul c elementele rmase
n vectorul a (se
execut c[k]=a[i], k=k+1, i=i+1 pn cnd i devine egal cu lungimea n a vectorului a); altfel, s-a
epuizat vectorul a i se vor aduga la vectorul c elementele rmase n vectorul b (se execut
c[k]=b[j], k=k+1, j=j+1 pn cnd j devine egal cu lungimea m a vectorului b).

10
#include<iostream>
using namespace std;
void main()
{
int i,j,k,n,m,a[50],b[50],c[100];
cout<<"Introduceti dimensiunea primului vector : "; cin>>n;
cout<<"Introduceti dimensiunea celui de al doilea vector : "; cin>>m;
// se citesc cei doi vectori ordonati deja crescator ! 9
cout<<endl;
cout<<"ATENTIE! Vectorii trebuie introdusi ordonati
crescator"<<endl<<endl;
cout<<"Componentele primului vector"<<endl;
for(i=0;i<n;i++) {
cout<<"a["<<i<<"]=";
cin>>a[i];
}
cout<<"Componentele celui de al doilea vector"<<endl;
for(j=0;j<m;j++) {
cout<<"b["<<j<<"]=";
cin>>b[j];
}
// incepe interclasarea celor doi vectori
i=0; j=0; k=0;
while(i<n && j<m) {
if(a[i]<b[j]) {
c[k]=a[i];
i=i+1;
}
else {
c[k]=b[j];
j=j+1;
}
k=k+1;
}
if(i<n)
while(i<n) {
c[k]=a[i];
k=k+1; i=i+1;
}
else
while(j<m) {
c[k]=b[j];
k=k+1; j=j+1;
}
// este afisat vectorul obtinut
for(k=0;k<n+m;k++)
cout<<c[k]<<" ";
cout<<endl;
}

11

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