Graf Temelleri Graph Fundamentals

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
ABCDEV = {A, B, C, D, E}   |V| = 5E = {AB, AD, AE, BC, CD, DE}   |E| = 6

Graf Terminolojisi

Temel Kavramlar

TerimİngilizceAçıklama
DüğümVertex / NodeGrafın temel birimi. Bir varlığı temsil eder.
KenarEdge / Arcİki düğüm arasındaki bağlantı. İlişkiyi temsil eder.
KomşuAdjacentKenarla doğrudan bağlı iki düğüm birbirine komşudur.
DereceDegreeBir düğüme bağlı kenar sayısı. deg(A) = 3 (yukarıdaki grafta).
YolPathDüğümler arasındaki kenar dizisi. A→B→C bir yoldur.
DöngüCycleBaşlangıç = bitiş olan yol. A→D→E→A bir döngüdür.
Bağlı grafConnectedHer düğüm çifti arasında en az bir yol var.
AğaçTreeBağ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)
ABC
Her düğüm en fazla 1 kez
Uzunluk = 2 (kenar sayısı)
Döngü (Cycle)
ADEA
Başlangıç = bitiş
Uzunluk = 3
Hamilton Yolu
EABCD
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
Alideg=2Ayşedeg=3Candeg=2Denizdeg=3{Ali,Ayşe} = {Ayşe,Ali} → yönsüzΣ derece = 2+3+2+3 = 10 = 2×5 kenar ✓

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
Aliout=2 in=1Ayşeout=2 in=2Canout=0 in=2Denizout=2 in=1(Ali, Ayşe) ≠ (Ayşe, Ali) → yönlüAli↔Ayşe: karşılıklı takip (2 ayrı kenar)Can: in=2, out=0 → "takipçi var ama kimseyi takip etmiyor"

Giriş ve Çıkış Derecesi

TerimİngilizceAçıklama
Çıkış derecesiOut-degreeDüğümden çıkan kenar sayısı. out(Ali) = 2
Giriş derecesiIn-degreeDüğüme giren kenar sayısı. in(Can) = 2
Kaynak (source)Sourcein-degree = 0 olan düğüm. Sadece veren.
Havuz (sink)Sinkout-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)
250580450335270390190680AnkaraİstanbulBursaEskişehirKonyaİzmir
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

ÖzellikYönsüzYö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)
Derecedeg(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
ÖrnekArkadaşlık, yol ağıTwitter, web linkleriHarita, ağ bant genişliği
Matris simetrisiSimetrik ✓AsimetrikHer 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.

Graf Gösterimi 1: Komşuluk Matrisi (Adjacency Matrix)

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)

Yönsüz Graf — Matris Örneği

5 Düğümlü Yönsüz Graf → Komşuluk Matrisi
01235 kenar, yönsüz
0123
00111
11010
21101
31010
Simetrik: matris[i][j] = matris[j][i] ✓

Yönlü Graf — Matris Örneği

4 Düğümlü Yönlü Graf → Asimetrik Matris
0123
0123
00101
10010
20001
30100
Asimetrik: matris[0][1]=1 ama matris[1][0]=0
Satır = kaynak, Sütun = hedef. matris[i][j]=1 → i'den j'ye kenar var.
Satır toplamı = out-degree, Sütun toplamı = in-degree.

Ağırlıklı Graf — Matris Örneği

Ağırlıklı Yönsüz → Matrise Ağırlık Yazılır (kenar yoksa ∞)
AnkaraİstanbulEskişehirKonya
Ankara0250450580
İstanbul2500335
Eskişehir4503350390
Konya5803900
İ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>

typedef struct {
    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 */
void matrisKenarEkle(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ı? */
bool matrisKenarVar(MatrisGraf* g, int src, int dst) {
    return g->matris[src][dst] != 0;
}

/* Düğümün komşularını listele */
void matrisKomsular(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 */
void matrisYazdir(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!

Graf Gösterimi 2: Komşuluk Listesi (Adjacency List)

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
0123
0
123→ ∅
1
02→ ∅
2
013→ ∅
3
02→ ∅
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ü */
typedef struct KomsulukNode {
    int hedef;           // komşu düğüm ID
    int agirlik;         // kenar ağırlığı (ağırlıksızsa 1)
    struct KomsulukNode* next;
} KomsulukNode;

/* Graf yapısı */
typedef struct {
    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 */
static KomsulukNode* yeniNode(int hedef, int agirlik) {
    KomsulukNode* n = malloc(sizeof(KomsulukNode));
    n->hedef   = hedef;
    n->agirlik = agirlik;
    n->next    = NULL;
    return n;
}

/* Kenar ekle */
void listeKenarEkle(ListeGraf* g, int src, int dst, int agirlik) {
    // src → dst
    KomsulukNode* 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 */
void listeKomsular(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 */
void listeGrafYazdir(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)) */
bool listeKenarVar(ListeGraf* g, int src, int dst) {
    KomsulukNode* curr = g->listeler[src];
    while (curr) {
        if (curr->hedef == dst) return true;
        curr = curr->next;
    }
    return false;
}

/* Düğüm derecesi */
int listeDerece(ListeGraf* g, int v) {
    int deg = 0;
    KomsulukNode* curr = g->listeler[v];
    while (curr) { deg++; curr = curr->next; }
    return deg;
}

Demo — Tam Kullanım

main() — graf oluştur ve test et
int main() {
    // ── Yönsüz graf ──
    ListeGraf* g = listeGrafOlustur(4, false);
    listeKenarEkle(g, 0, 1, 1);
    listeKenarEkle(g, 0, 2, 1);
    listeKenarEkle(g, 0, 3, 1);
    listeKenarEkle(g, 1, 2, 1);
    listeKenarEkle(g, 2, 3, 1);
    listeGrafYazdir(g);

    printf("\nKenar (0,2): %s\n",
           listeKenarVar(g,0,2) ? "var ✓" : "yok");
    printf("Kenar (1,3): %s\n",
           listeKenarVar(g,1,3) ? "var" : "yok ✗");
    printf("deg(0)=%d, deg(1)=%d\n",
           listeDerece(g,0), listeDerece(g,1));

    // ── Ağırlıklı yönlü graf ──
    printf("\n── Ağırlıklı Yönlü Graf ──\n");
    ListeGraf* dg = listeGrafOlustur(4, true);
    listeKenarEkle(dg, 0, 1, 250);  // Ankara→İstanbul
    listeKenarEkle(dg, 0, 2, 450);  // Ankara→Eskişehir
    listeKenarEkle(dg, 2, 1, 335);  // Eskişehir→İstanbul
    listeKenarEkle(dg, 2, 3, 390);  // Eskişehir→Konya
    listeGrafYazdir(dg);

    return 0;
}
çıktı
Graf: 4 düğüm, 5 kenar (yönsüz)
[0] → 3(1) 2(1) 1(1) ∅
[1] → 2(1) 0(1) ∅
[2] → 3(1) 1(1) 0(1) ∅
[3] → 2(1) 0(1) ∅

Kenar (0,2): var ✓
Kenar (1,3): yok ✗
deg(0)=3, deg(1)=2

── Ağırlıklı Yönlü Graf ──
Graf: 4 düğüm, 4 kenar (yönlü)
[0] → 2(450) 1(250) ∅          ← Ankara: Eskişehir(450km), İstanbul(250km)
[1] → ∅                         ← İstanbul: giden kenar yok (sink)
[2] → 3(390) 1(335) ∅          ← Eskişehir: Konya(390), İstanbul(335)
[3] → ∅                         ← Konya: giden kenar yok

Komşuluk Matrisi vs Komşuluk Listesi

Karmaşıklık Karşılaştırması

İşlemMatrisListeKazanan
Kenar var mı?
u→v kenarı kontrol
O(1) ✓O(deg(u))Matris
Kenar ekleO(1) ✓O(1) ✓Berabere
Kenar silO(1) ✓O(deg(u))Matris
Komşuları listele
u'nun tüm komşuları
O(V)O(deg(u)) ✓Liste
Tüm kenarları dolaşO(V²)O(V + E) ✓Liste
BFS / DFSO(V²)O(V + E) ✓Liste
Düğüm derecesiO(V)O(deg(v)) ✓Liste
BellekO(V²)O(V + E) ✓Liste

Bellek Karşılaştırması — Gerçek Dünya Sayıları

GrafVEMatris BellekListe BellekFark
Küçük ağ10050040 KB~8 KB
Orta ağ10K50K400 MB~800 KB500×
Web grafi1M10M4 TB (!)~160 MB25.000×
Facebook3B~500B36 EB (!!)~8 TB4M×
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ı

AlanDüğümlerKenarlarTürAlgoritma
Sosyal ağKullanıcılarArkadaşlık / takipYönsüz / YönlüBFS (öneri), PageRank
GPS navigasyonKavşaklarYollar (mesafe)Ağırlıklı yönlüDijkstra, A*
InternetRouterlarBağlantılar (bant)AğırlıklıShortest path, spanning tree
WebSayfalarHyperlinkYönlüPageRank, web crawler (BFS)
DerleyiciİşlemlerBağımlılıklarDAGTopolojik sıralama
Oyun AIDurumlarAksiyonlarYönlüBFS, DFS, minimax
BiyolojiProteinlerEtkileşimlerYönsüzKümeleme, topluluk tespiti
VeritabanıTablolarForeign key ilişkileriYö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.
← Veri Yapıları