Biblioteca
Tutora
BibliotecaInformatică și TIC › clasa a IX-a

Structuri de date

Studiul tablourilor unidimensionale și bidimensionale ca modalități de organizare a datelor în memorie.

Bacalaureat

Tablouri unidimensionale (vectori)

Un tablou unidimensional (vector) este o colecție de elemente de același tip, memorate contiguu (una lângă alta) în memorie și identificate printr-un singur nume plus un indice. În C++ declarația int v[100]; rezervă loc pentru 100 de întregi, iar elementele se accesează cu v[0], v[1], ..., v[99].

Două lucruri trebuie fixate de la început, pentru că generează cele mai multe erori:

În pseudocodul de bacalaureat vectorii apar deseori indexați de la 1 la n — citește cu atenție enunțul, pentru că un raționament corect cu indexare greșită dă rezultat greșit.

Avantajul esențial al vectorului: accesul la orice element se face direct, în timp constant, cunoscând doar indicele — spre deosebire de datele citite una câte una, pe care nu le mai poți revizita.

Parcurgerea și prelucrările elementare

Parcurgerea înseamnă vizitarea elementelor unui vector, de regulă de la primul la ultimul, cu o structură pentru: pentru i ← 0, n-1 execută prelucrează v[i]. Pe acest schelet se construiesc prelucrările standard:

O idee care apare des în subiecte: parcurgerea simultană de la ambele capete (i de la început, j de la sfârșit) — de exemplu pentru a verifica dacă vectorul e palindrom sau pentru a-l inversa fără vector suplimentar, interschimbând v[i] cu v[j] cât timp i < j.

Sortarea unui vector

A sorta înseamnă a rearanja elementele în ordine crescătoare sau descrescătoare. Doi algoritmi elementari sunt de știut cu pașii lor:

Operația de bază a ambilor este interschimbarea (swap) a două elemente, care cere o variabilă auxiliară: aux ← a; a ← b; b ← aux. Scrierea a ← b; b ← a pierde valoarea inițială a lui a — ambele variabile rămân cu valoarea lui b.

De reținut și utilitatea sortării: într-un vector sortat, minimul și maximul sunt la capete, elementele egale devin vecine (utile la eliminarea duplicatelor), iar căutarea unei valori poate folosi metode mult mai rapide decât parcurgerea completă.

Tablouri bidimensionale (matrice)

Un tablou bidimensional (matrice) organizează datele pe linii și coloane: int a[10][10]; declară o matrice, iar a[i][j] este elementul de pe linia i, coloana j — în această ordine, mereu. Inversarea indicilor (coloană, linie) este una dintre cele mai frecvente erori de punctaj.

Parcurgerea completă folosește două bucle imbricate: cea exterioară pentru linii, cea interioară pentru coloane. Cu bucla exterioară pe i și cea interioară pe j, matricea se parcurge pe linii; inversând buclele, se parcurge pe coloane.

Pentru o matrice pătratică (același număr n de linii și coloane) se definesc zonele clasice:

Prelucrări tipice de examen: suma elementelor de pe o linie dată, maximul de pe fiecare coloană, suma elementelor de pe diagonale, verificarea simetriei față de diagonala principală (a[i][j] = a[j][i] pentru orice i și j).

Subprograme care prelucrează tablouri

Prelucrările pe tablouri se împachetează natural în subprograme: o funcție care întoarce suma elementelor unui vector, o procedură care citește o matrice, o funcție care caută o valoare și întoarce poziția ei.

Particularitatea esențială în C++: tablourile se transmit prin adresă, nu prin valoare. Când dai un vector ca parametru unei funcții, funcția NU primește o copie, ci lucrează direct pe elementele originale — orice modificare făcută în subprogram rămâne după revenirea din apel. La variabilele simple (int, double) e invers: implicit se transmite o copie, iar modificările se pierd.

Consecințe practice:

Descompunerea în subprograme nu e doar eleganță: subiectul III de la bacalaureat cere explicit definirea unor subprograme cu antet impus, deci exersarea scrierii lor corecte (tip returnat, parametri, apel) aduce puncte direct.

De reținut

tablou unidimensional (vector)
structură de date omogenă în care elementele de același tip sunt memorate contiguu și accesate prin nume și indice
indice
numărul care identifică poziția unui element în tablou; în C++ primul element are indicele 0, iar ultimul dintre cele n are indicele n-1
parcurgere
vizitarea pe rând a elementelor unui tablou, de regulă cu o structură repetitivă cu contor, pentru a le prelucra
căutare secvențială
examinarea elementelor unui vector unul câte unul, până la găsirea valorii căutate sau până la epuizarea vectorului
sortare prin selecție
metodă de ordonare care la fiecare pas alege minimul (sau maximul) din zona nesortată și îl interschimbă cu primul element al acesteia
interschimbare (swap)
schimbarea valorilor a două variabile între ele folosind o a treia variabilă auxiliară: aux ← a; a ← b; b ← aux
matrice
tablou bidimensional organizat pe linii și coloane, în care a[i][j] este elementul de pe linia i și coloana j
diagonala principală
în matricea pătratică, mulțimea elementelor a[i][i], adică cele pentru care indicele liniei este egal cu indicele coloanei
diagonala secundară
în matricea pătratică cu n linii indexate de la 0, elementele pentru care suma indicilor este n-1
transmiterea tablourilor ca parametri
în C++ tablourile se transmit prin adresă: subprogramul lucrează pe elementele originale, iar modificările rămân după apel

Greșeli frecvente

Greșit: Ultimul element al unui vector cu n elemente ar fi v[n]
Corect: La indexare de la 0, ultimul element este v[n-1]; accesarea lui v[n] iese în afara tabloului — eroarea off by one care strică și buclele scrise cu <= în loc de <
Greșit: Minimul unui vector se inițializează cu 0
Corect: Minimul se inițializează cu primul element al vectorului (sau maximul cu primul element); inițializarea cu 0 dă rezultat fals pe vectori cu toate elementele pozitive, unde 0 nici nu apare
Greșit: Interschimbarea a două variabile s-ar face prin a ← b; b ← a
Corect: Fără variabilă auxiliară prima atribuire distruge valoarea lui a, iar ambele variabile ajung egale cu b; corect: aux ← a; a ← b; b ← aux
Greșit: a[i][j] ar fi elementul de pe coloana i și linia j
Corect: Primul indice este întotdeauna linia, al doilea coloana: a[i][j] = linia i, coloana j; inversarea lor face ca parcurgerea pe linii să devină pe coloane și invers
Greșit: Un vector transmis ca parametru unei funcții ar rămâne nemodificat, ca variabilele simple
Corect: Tablourile se transmit prin adresă: funcția modifică direct elementele originale; doar variabilele simple transmise prin valoare rămân neschimbate după apel

Test — 6 întrebări ca la examen

1. Un vector v cu 50 de elemente este indexat de la 0. Care este indicele ultimului element?
  1. 50
  2. 49
  3. 51
  4. 0
Vezi răspunsul
49. Elementele au indicii 0, 1, ..., 49 — în total 50. Varianta 50 este eroarea off by one: pare naturală pentru că vectorul are 50 de elemente, dar v[50] ar fi al 51-lea element, aflat în afara tabloului.
2. Pentru vectorul v = (3, 9, 2, 7), ce afișează secvența: m ← v[0]; pentru i ← 1, 3 execută dacă v[i] < m atunci m ← v[i]; scrie m?
  1. 9
  2. 3
  3. 2
  4. 7
Vezi răspunsul
2. Algoritmul determină minimul: m pornește de la 3, rămâne 3 la compararea cu 9, devine 2 la compararea cu v[2], iar 7 nu îl mai schimbă. Varianta 9 corespunde citirii greșite a semnului < ca > (adică maximul).
3. Într-o matrice pătratică cu 5 linii și 5 coloane, indexată de la 0, elementul a[1][3] se află pe:
  1. linia 3, coloana 1
  2. linia 1, coloana 3
  3. diagonala principală
  4. linia 2, coloana 4
Vezi răspunsul
linia 1, coloana 3. Primul indice este linia, al doilea coloana, deci a[1][3] e pe linia 1, coloana 3. Prima variantă inversează indicii — cea mai frecventă greșeală la matrice. Nu e pe diagonala principală pentru că 1 ≠ 3.
4. Într-o matrice pătratică cu n = 6 (indexare de la 0), un element a[i][j] este pe diagonala secundară dacă:
  1. i = j
  2. i + j = 6
  3. i + j = 5
  4. i - j = 5
Vezi răspunsul
i + j = 5. Pe diagonala secundară suma indicilor este n - 1 = 5: elementele a[0][5], a[1][4], ..., a[5][0]. Varianta i + j = 6 uită că indexarea începe de la 0 (ar fi corectă la indexarea de la 1), iar i = j descrie diagonala principală.
5. La sortarea prin selecție crescătoare a vectorului (8, 3, 5, 1), ce conține vectorul după PRIMUL pas complet?
  1. (3, 8, 5, 1)
  2. (1, 3, 5, 8)
  3. (3, 5, 1, 8)
  4. (1, 8, 5, 3)
Vezi răspunsul
(1, 8, 5, 3). Selecția caută minimul întregului vector (1, aflat pe ultima poziție) și îl interschimbă cu primul element: 8 ajunge unde era 1, deci rezultă (1, 8, 5, 3). Varianta (3, 8, 5, 1) descrie bubble sort, care interschimbă doar vecini — confuzia clasică între cele două metode.
6. O funcție void f(int v[], int n) dublează fiecare element al vectorului primit. Ce se întâmplă cu vectorul din programul principal după apelul f(a, n)?
  1. rămâne neschimbat, pentru că funcția lucrează pe o copie
  2. elementele lui sunt dublate, pentru că tablourile se transmit prin adresă
  3. se dublează doar primul element
  4. programul nu se compilează, pentru că funcția void nu poate modifica nimic
Vezi răspunsul
elementele lui sunt dublate, pentru că tablourile se transmit prin adresă. Tablourile se transmit prin adresă: funcția modifică direct elementele originale, deci după apel toate valorile din a sunt dublate. Prima variantă e tentantă pentru că descrie corect comportamentul variabilelor simple transmise prin valoare — dar tablourile sunt excepția.
Deschide varianta interactivă — cu AI care îți explică
← Algoritmi și dateSubprograme →
BiologieChimieEconomieFilosofieFizicăGeografieInformatică și TICIstorieLogică și argumentareMatematicăPsihologieLimba și literatura română