Graf nedir, düğüm, kenar, derece, yol, döngü terminolojisi, yönlü, yönsüz ve ağırlıklı graf türleri, komşuluk matrisi ve komşuluk listesi gösterimleri — adım adım görseller ve C kodu.
🗂️ Veri Yapıları📅 22 February 2026👁️ 13 görüntülenme
Graf Nedir?
Graf, düğümler (vertices) ve bu düğümleri birbirine bağlayan kenarlardan (edges) oluşan bir veri yapısıdır. Matematiksel olarak G = (V, E) — V düğümler kümesi, E kenarlar kümesidir. Ağaçlar, bağlı listeler ve hatta diziler aslında grafın özel halleridir.
Graflar neden önemli? Gerçek dünya ilişkilerinin çoğu graf yapısındadır: sosyal ağlar (kişiler = düğüm, arkadaşlık = kenar), haritalar (şehirler = düğüm, yollar = kenar), internet (sayfalar = düğüm, linkler = kenar), bilgisayar ağları, molekül yapıları, bağımlılık yönetimi, oyun yapay zekası, GPS navigasyon... Grafları anlamak, bu problemleri çözmek demektir.
Basit Bir Graf — 5 Düğüm, 6 Kenar
Graf Terminolojisi
Temel Kavramlar
Terim
İngilizce
Açıklama
Düğüm
Vertex / Node
Grafın temel birimi. Bir varlığı temsil eder.
Kenar
Edge / Arc
İki düğüm arasındaki bağlantı. İlişkiyi temsil eder.
Komşu
Adjacent
Kenarla doğrudan bağlı iki düğüm birbirine komşudur.
Derece
Degree
Bir düğüme bağlı kenar sayısı. deg(A) = 3 (yukarıdaki grafta).
Yol
Path
Düğümler arasındaki kenar dizisi. A→B→C bir yoldur.
Döngü
Cycle
Başlangıç = bitiş olan yol. A→D→E→A bir döngüdür.
Bağlı graf
Connected
Her düğüm çifti arasında en az bir yol var.
Ağaç
Tree
Bağlı, döngüsüz graf. |E| = |V| - 1.
Derece (Degree) — Detay
Düğüm Dereceleri — Yukarıdaki Graf İçin
A
deg = 3
B, D, E
B
deg = 2
A, C
C
deg = 2
B, D
D
deg = 3
A, C, E
E
deg = 2
A, D
Tokalaşma Teoremi: Tüm derecelerin toplamı = 2 × kenar sayısı → 3+2+2+3+2 = 12 = 2×6 ✓
Yol ve Döngü
Yol ve Döngü Örnekleri
Basit Yol (Simple Path)
A→B→C
Her düğüm en fazla 1 kez Uzunluk = 2 (kenar sayısı)
Döngü (Cycle)
A→D→E→A
Başlangıç = bitiş Uzunluk = 3
Hamilton Yolu
E→A→B→C→D
Her düğüm tam 1 kez Tüm düğümleri ziyaret
Ağaç vs Graf: Ağaç = bağlı + döngüsüz graf. n düğümlü bir ağaçta tam olarak n-1 kenar vardır. Eğer bir grafa n-1'den fazla kenar eklerseniz, en az bir döngü oluşur. Ağaçlar önceki bölümlerde gördüğümüz BST, AVL, B-Tree gibi yapılardır — hepsi aslında grafın özel halleridir.
Graf Türleri
Yönsüz Graf (Undirected Graph)
Kenarların yönü yoktur — A ile B arasındaki kenar her iki yönde de geçerlidir. Arkadaşlık ilişkisi gibi: "Ali, Ayşe'nin arkadaşı" ise "Ayşe de Ali'nin arkadaşı"dır.
Yönsüz Graf — Sosyal Ağ Örneği
Yönlü Graf (Directed Graph / Digraph)
Her kenarın bir yönü vardır — (A, B) kenarı A'dan B'ye gider ama B'den A'ya gitmez (aksi de eklenmedikçe). Twitter takip sistemi gibi: "Ali, Ayşe'yi takip ediyor" ama "Ayşe Ali'yi takip etmeyebilir".
Yönlü Graf — Twitter Takip Örneği
Giriş ve Çıkış Derecesi
Terim
İngilizce
Açıklama
Çıkış derecesi
Out-degree
Düğümden çıkan kenar sayısı. out(Ali) = 2
Giriş derecesi
In-degree
Düğüme giren kenar sayısı. in(Can) = 2
Kaynak (source)
Source
in-degree = 0 olan düğüm. Sadece veren.
Havuz (sink)
Sink
out-degree = 0 olan düğüm. Can = sink (sadece alan).
Yönlü graf kuralı: Σ out-degree = Σ in-degree = |E|. Yukarıdaki grafta: out toplam = 2+2+0+2 = 6, in toplam = 1+2+2+1 = 6 = kenar sayısı ✓
Ağırlıklı Graf (Weighted Graph)
Her kenara bir ağırlık (weight) / maliyet (cost) atanmış graftır. Harita örneğinde: düğümler = şehirler, kenarlar = yollar, ağırlıklar = mesafe (km) veya süre (saat).
Ağırlıklı Yönsüz Graf — Şehirler Arası Mesafe (km)
Ankara→İstanbul: 250 km (direkt) vs Ankara→Eskişehir→Bursa→İstanbul: 450+270+335 = 1055 km En kısa yol problemi → Dijkstra algoritması (sonraki bölüm)
Graf Türleri — Karşılaştırma Tablosu
Özellik
Yönsüz
Yönlü
Ağırlıklı
Kenar yönü
Yok (çift yönlü)
Var (tek yönlü)
Her ikisi olabilir
Kenar gösterimi
{u, v} = {v, u}
(u, v) ≠ (v, u)
(u, v, w)
Derece
deg(v)
in(v) + out(v)
deg(v) + ağırlıklar
Kenar sayısı (maks)
|V|×(|V|-1)/2
|V|×(|V|-1)
Aynı + ağırlık bilgisi
Örnek
Arkadaşlık, yol ağı
Twitter, web linkleri
Harita, ağ bant genişliği
Matris simetrisi
Simetrik ✓
Asimetrik
Her ikisi olabilir
Özel graf türleri: DAG (Directed Acyclic Graph): Yönlü + döngüsüz graf. İş bağımlılıkları, derleyici, topolojik sıralama. Tam graf (Complete): Her düğüm çifti arasında kenar var. Kn: n düğüm, n(n-1)/2 kenar. İki parçalı (Bipartite): Düğümler 2 gruba ayrılır, kenarlar sadece gruplar arası. Eşleştirme problemleri. Seyrek (Sparse): |E| ≪ |V|². Çoğu gerçek dünya grafi seyrek → komşuluk listesi tercih. Yoğun (Dense): |E| ≈ |V|². Az düğüm, çok kenar → komşuluk matrisi tercih.
Komşuluk matrisi, grafı |V| × |V| boyutunda iki boyutlu bir dizi ile temsil eder. Eğer i düğümünden j düğümüne kenar varsa matris[i][j] = 1 (veya ağırlık değeri), yoksa 0 olur.
Komşuluk Matrisi kuralları: • Yönsüz graf: Matris simetrik → matris[i][j] = matris[j][i] • Yönlü graf: Matris asimetrik olabilir → (i→j) varsa matris[i][j]=1, (j→i) yoksa matris[j][i]=0 • Ağırlıklı graf: 0/1 yerine ağırlık değeri saklanır. Kenar yoksa 0 veya ∞ • Köşegen: matris[i][i] = 0 (self-loop yoksa)
Ağırlıklı Yönsüz → Matrise Ağırlık Yazılır (kenar yoksa ∞)
Ankara
İstanbul
Eskişehir
Konya
Ankara
0
250
450
580
İstanbul
250
0
335
∞
Eskişehir
450
335
0
390
Konya
580
∞
390
0
İstanbul↔Konya direkt yol yok → ∞. Matris yine simetrik (yönsüz).
Komşuluk Matrisi — C Implementasyonu
adjacency_matrix.c
#include<stdio.h>#include<stdlib.h>#include<stdbool.h>typedefstruct {
int** matris;
int dugumSayisi;
bool yonlu;
} MatrisGraf;
/* Graf oluştur */MatrisGraf* matrisGrafOlustur(int V, bool yonlu) {
MatrisGraf* g = malloc(sizeof(MatrisGraf));
g->dugumSayisi = V;
g->yonlu = yonlu;
g->matris = malloc(V * sizeof(int*));
for (int i = 0; i < V; i++) {
g->matris[i] = calloc(V, sizeof(int));
}
return g;
}
/* Kenar ekle */voidmatrisKenarEkle(MatrisGraf* g, int src, int dst, int agirlik) {
g->matris[src][dst] = agirlik;
if (!g->yonlu)
g->matris[dst][src] = agirlik; // yönsüz → simetrik
}
/* Kenar var mı? */boolmatrisKenarVar(MatrisGraf* g, int src, int dst) {
return g->matris[src][dst] != 0;
}
/* Düğümün komşularını listele */voidmatrisKomsular(MatrisGraf* g, int v) {
printf("Düğüm %d komşuları: ", v);
for (int i = 0; i < g->dugumSayisi; i++)
if (g->matris[v][i] != 0)
printf("%d(%d) ", i, g->matris[v][i]);
printf("\n");
}
/* Matris yazdır */voidmatrisYazdir(MatrisGraf* g) {
printf(" ");
for (int j = 0; j < g->dugumSayisi; j++)
printf("%3d", j);
printf("\n");
for (int i = 0; i < g->dugumSayisi; i++) {
printf("[%d] ", i);
for (int j = 0; j < g->dugumSayisi; j++)
printf("%3d", g->matris[i][j]);
printf("\n");
}
}
Matrisin zayıflığı — bellek: V düğümlü grafta matris V² hücre tutar. 10.000 düğüm → 10.000² = 100 milyon hücre = ~400 MB (int). Ama sosyal ağda kişi başı ortalama 150 arkadaş olsa → toplam kenar ≈ 750K. Matristeki 100M hücrenin %99.25'i sıfır — devasa israf!
Komşuluk listesi, her düğüm için o düğümün komşularının listesini tutar. Genellikle bir dizi + bağlı listeler yapısıdır: dizi indeksi = düğüm numarası, listelerdeki elemanlar = komşu düğümler.
Neden komşuluk listesi tercih edilir? Çoğu gerçek dünya grafi seyrek (sparse)'tir — her düğümün az sayıda komşusu vardır. Facebook'ta ortalama 338 arkadaş var ama 3 milyar kullanıcı → matris 9×1018 hücre, liste sadece ~1 milyar entry. Bellek farkı: milyonlarca kat!
Yönsüz Graf — Komşuluk Listesi
Aynı 4 Düğümlü Graf → Komşuluk Listesi
0
→
1→2→3→ ∅
1
→
0→2→ ∅
2
→
0→1→3→ ∅
3
→
0→2→ ∅
Yönsüz graf: kenar (0,2) → hem 0'ın listesinde 2 var, hem 2'nin listesinde 0 var. Toplam düğüm sayısı (listelerde) = 2 × kenar sayısı = 2×5 = 10 ✓
Komşuluk Listesi — C Implementasyonu
adjacency_list.c
/* Komşuluk listesi düğümü */typedefstructKomsulukNode {
int hedef; // komşu düğüm IDint agirlik; // kenar ağırlığı (ağırlıksızsa 1)structKomsulukNode* next;
} KomsulukNode;
/* Graf yapısı */typedefstruct {
KomsulukNode** listeler; // her düğüm için bağlı liste başıint dugumSayisi;
int kenarSayisi;
bool yonlu;
} ListeGraf;
/* Graf oluştur */ListeGraf* listeGrafOlustur(int V, bool yonlu) {
ListeGraf* g = malloc(sizeof(ListeGraf));
g->dugumSayisi = V;
g->kenarSayisi = 0;
g->yonlu = yonlu;
g->listeler = calloc(V, sizeof(KomsulukNode*));
return g;
}
/* Yardımcı — listeye düğüm ekle */staticKomsulukNode* yeniNode(int hedef, int agirlik) {
KomsulukNode* n = malloc(sizeof(KomsulukNode));
n->hedef = hedef;
n->agirlik = agirlik;
n->next = NULL;
return n;
}
/* Kenar ekle */voidlisteKenarEkle(ListeGraf* g, int src, int dst, int agirlik) {
// src → dstKomsulukNode* n = yeniNode(dst, agirlik);
n->next = g->listeler[src];
g->listeler[src] = n;
if (!g->yonlu) {
// dst → src (yönsüz → çift yönlü)
n = yeniNode(src, agirlik);
n->next = g->listeler[dst];
g->listeler[dst] = n;
}
g->kenarSayisi++;
}
/* Komşuları listele */voidlisteKomsular(ListeGraf* g, int v) {
printf("[%d] → ", v);
KomsulukNode* curr = g->listeler[v];
while (curr) {
printf("%d(%d) ", curr->hedef, curr->agirlik);
curr = curr->next;
}
printf("∅\n");
}
/* Tüm grafı yazdır */voidlisteGrafYazdir(ListeGraf* g) {
printf("Graf: %d düğüm, %d kenar (%s)\n",
g->dugumSayisi, g->kenarSayisi,
g->yonlu ? "yönlü" : "yönsüz");
for (int i = 0; i < g->dugumSayisi; i++)
listeKomsular(g, i);
}
/* Kenar var mı? — O(deg(src)) */boollisteKenarVar(ListeGraf* g, int src, int dst) {
KomsulukNode* curr = g->listeler[src];
while (curr) {
if (curr->hedef == dst) returntrue;
curr = curr->next;
}
returnfalse;
}
/* Düğüm derecesi */intlisteDerece(ListeGraf* g, int v) {
int deg = 0;
KomsulukNode* curr = g->listeler[v];
while (curr) { deg++; curr = curr->next; }
return deg;
}
Matris: V² × 4 byte (int). Liste: V × 8 byte (pointer) + E × 12 byte (hedef+ağırlık+next). Seyrek graflarda E ≪ V² → liste çok daha verimli.
Hangi Gösterimi Kullanmalıyım?
Matris Seç — Eğer:
• Graf yoğun (dense): E ≈ V² • Kenar sorgulama çok sık: "u→v var mı?" • V küçük (<1000) • Floyd-Warshall gibi matris tabanlı algoritmalar kullanılacak • Basit implementasyon istiyorsan
Liste Seç — Eğer:
• Graf seyrek (sparse): E ≪ V² • BFS, DFS, Dijkstra kullanılacak • V büyük (>1000) • Komşu dolaşımı ana işlem • Bellek kısıtlı • Çoğu gerçek dünya grafi → LİSTE
Grafların Gerçek Dünya Kullanımları
Alan
Düğümler
Kenarlar
Tür
Algoritma
Sosyal ağ
Kullanıcılar
Arkadaşlık / takip
Yönsüz / Yönlü
BFS (öneri), PageRank
GPS navigasyon
Kavşaklar
Yollar (mesafe)
Ağırlıklı yönlü
Dijkstra, A*
Internet
Routerlar
Bağlantılar (bant)
Ağırlıklı
Shortest path, spanning tree
Web
Sayfalar
Hyperlink
Yönlü
PageRank, web crawler (BFS)
Derleyici
İşlemler
Bağımlılıklar
DAG
Topolojik sıralama
Oyun AI
Durumlar
Aksiyonlar
Yönlü
BFS, DFS, minimax
Biyoloji
Proteinler
Etkileşimler
Yönsüz
Kümeleme, topluluk tespiti
Veritabanı
Tablolar
Foreign key ilişkileri
Yönlü
Join sıralaması
Sonuç
Graf, düğümler ve kenarlardan oluşan ve gerçek dünyadaki ilişkileri modellemeye yarayan temel veri yapısıdır. Düğüm, kenar, derece, yol, döngü gibi terimler grafın temel alfabesidir. Her graf problemi bu terminoloji ile ifade edilir.
Graflar üç ana türe ayrılır: yönsüz (kenarlar çift yönlü — arkadaşlık gibi), yönlü (kenarlar tek yönlü — Twitter takip gibi) ve ağırlıklı (kenarlara maliyet/mesafe atanmış — harita gibi). Yönlü graflarda giriş ve çıkış derecesi ayrı ayrı takip edilir.
Grafı bellekte iki şekilde temsil ederiz: Komşuluk matrisi V×V boyutunda 2D dizidir — kenar sorgulama O(1) ama bellek O(V²). Komşuluk listesi her düğüm için bağlı liste tutar — bellek O(V+E), dolaşma O(V+E). Seyrek graflar (çoğu gerçek dünya grafi) için komşuluk listesi açık ara daha verimlidir.
Bölüm 8.1 özeti: Graf G=(V,E): düğümler + kenarlar. Terminoloji: düğüm (vertex), kenar (edge), derece (degree), yol (path), döngü (cycle), bağlı (connected). Tokalaşma teoremi: Σdeg = 2|E|. Türler: yönsüz ({u,v}={v,u}, simetrik matris), yönlü ((u,v)≠(v,u), in/out-degree), ağırlıklı (kenar maliyetli). DAG = yönlü + döngüsüz. Gösterim 1 — Komşuluk Matrisi: V×V dizi, kenar sorgu O(1), bellek O(V²), yoğun graflar ve küçük V için. Gösterim 2 — Komşuluk Listesi: dizi + bağlı listeler, dolaşma O(V+E), bellek O(V+E), seyrek graflar ve büyük V için → çoğu durumda tercih. Sonraki bölüm: BFS ve DFS ile graf dolaşma.