Graf ako matica
Implementácia
#include <iostream>
using namespace std;
class Graph {
private:
int **matrix;
int number_of_vertices;
public:
explicit Graph(int numberOfVertices) {
this->number_of_vertices = numberOfVertices;
matrix = new int *[numberOfVertices];
for (int i = 0; i < numberOfVertices; i++) {
matrix[i] = new int[numberOfVertices];
for (int j = 0; j < numberOfVertices; j++) {
matrix[i][j] = 0;
}
}
}
void add_edge(int vertex1, int vertex2) const {
add_edge(vertex1, vertex2, 1);
}
void add_edge(int vertex1, int vertex2, int weight) const {
matrix[vertex1][vertex2] = weight;
matrix[vertex2][vertex1] = weight;
}
void remove_edge(int vertex1, int vertex2) const {
matrix[vertex1][vertex2] = 0;
matrix[vertex2][vertex1] = 0;
}
void print() const {
for (int i = 0; i < number_of_vertices; i++) {
cout << i << " : ";
for (int j = 0; j < number_of_vertices; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
~Graph() {
for (int i = 0; i < number_of_vertices; i++) {
delete[] matrix[i];
}
delete[] matrix;
}
};
int main() {
Graph graph(4);
graph.add_edge(0, 1, 1);
graph.add_edge(0, 2, 5);
graph.add_edge(1, 2, 2);
graph.add_edge(2, 0, 5);
graph.add_edge(2, 3, 3);
graph.print();
return 0;
}Vysvetlenie
1. Základné nastavenie
#include <iostream>
using namespace std;#include <iostream>– umožňuje použiť vstupno-výstupné toky (cin,cout).using namespace std;– zjednodušuje písanie (netreba každýkrát písaťstd::cout, stačícout).
2. Deklarácia triedy Graph
class Graph {
private:
int **matrix;
int number_of_vertices;matrix– dvojitý ukazovateľ naint, bude ukazovať na dynamicky alokovanú 2D maticu (rozmern × n).number_of_vertices– počet vrcholov v grafe.
3. Konštruktor
explicit Graph(int numberOfVertices) {
this->number_of_vertices = numberOfVertices;
matrix = new int *[numberOfVertices];
for (int i = 0; i < numberOfVertices; i++) {
matrix[i] = new int[numberOfVertices];
for (int j = 0; j < numberOfVertices; j++) {
matrix[i][j] = 0;
}
}
}- Uložíme si počet vrcholov.
- Dynamicky vytvoríme pole
matrixdĺžkynumberOfVertices, ktoré bude držať ukazovatele na riadky. - Pre každý riadok
i:- alokujeme pole
intdĺžkynumberOfVertices, - inicializujeme všetky položky na
0(t. j. žiadna hrana).
- alokujeme pole
4. Pridávanie a odstraňovanie hrán
4.1 Pridanie hrany so štandardnou váhou
void add_edge(int vertex1, int vertex2) const {
add_edge(vertex1, vertex2, 1);
}- Zavolá preťaženú verziu s váhou
1.
4.2 Pridanie hrany s vlastnou váhou
void add_edge(int vertex1, int vertex2, int weight) const {
matrix[vertex1][vertex2] = weight;
matrix[vertex2][vertex1] = weight;
}- Graf je neorientovaný, preto nastavíme oba smery:
vertex1 → vertex2ajvertex2 → vertex1.
4.3 Odstránenie hrany
void remove_edge(int vertex1, int vertex2) const {
matrix[vertex1][vertex2] = 0;
matrix[vertex2][vertex1] = 0;
}- Stačí vynulovať obe pozície v matici.
Note
Poznámka k const: metódy majú kvalifikátor const, ktorý hovorí, že nemenia vlastnosti objektu. V tomto prípade
však kvalifikátor nevzťahuje priamo na obsah matice (iba na ukazovateľ), takže úprava matrix[i][j] prebehne bez chyby
kompilátora.
5. Výpis matice susednosti
void print() const {
for (int i = 0; i < number_of_vertices; i++) {
cout << i << " : ";
for (int j = 0; j < number_of_vertices; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
}- Pre každý vrchol
ivypíšeme jeho index a potom v riadku hodnoty od0don−1, ktoré predstavujú váhy hrán.
Príklad výstupu pre 4 vrcholy:
0 : 0 1 5 0
1 : 1 0 2 0
2 : 5 2 0 3
3 : 0 0 3 0 6. Deštruktor
~Graph() {
for (int i = 0; i < number_of_vertices; i++) {
delete[] matrix[i];
}
delete[] matrix;
}- Uvoľníme pamäť zakúpenú konštruktorom:
- Vymažeme každý riadok (
delete[] matrix[i]). - Vymažeme pole ukazovateľov (
delete[] matrix).
- Vymažeme každý riadok (
7. Funkcia main
int main() {
Graph graph(4);
graph.add_edge(0, 1, 1);
graph.add_edge(0, 2, 5);
graph.add_edge(1, 2, 2);
graph.add_edge(2, 0, 5);
graph.add_edge(2, 3, 3);
graph.print();
return 0;
}- Vytvoríme graf so 4 vrcholmi.
- Pridáme hrany (napr.
0–1s váhou 1,0–2s váhou 5, atď.). - Zavoláme
print(), ktorý zobrazí celú maticu. - Pri ukončení funkcie
mainsa automaticky zavolá deštruktor~Graph(), ktorý uvoľní alokovanú pamäť.
Zhrnutie
- Reprezentácia grafu: matica susednosti
n × n, kdematrix[i][j]= váha hrany medzi vrcholmiiaj(alebo0, ak hrana neexistuje). - Výhody: rýchly prístup k informácii, či existuje hrana medzi dvoma vrcholmi (O(1)).
- Nevýhody: pamäťová náročnosť O(n²), aj keď málo hrán.
Tento jednoduchý príklad perfektne demonštruje dynamickú alokáciu, zodpovednosť za uvoľnenie pamäte a základné operácie nad neorientovaným váženým grafom.