Bölüm 2: Diziler ve Yapılar

Ardışık bellek, kayıtlar ve seyrek gösterimler
DiziAdres hesabıstructDinamik bellekMatrisSeyrek matris
C ile Veri Yapıları · İki ciltlik ders notları temel alınmıştır

Hazırlık

Başlamadan Önce

C ön bilgisi

Dizi, gösterge, struct, fonksiyon ve dinamik bellek temellerini hatırla.

İlk kavram

Dizi ve Adres hesabı

Bu bölümün hedefi

Dizi öğelerinin ardışık yerleşimini ve adres hesabını açıklamak.

Başlangıç sorusu

a[i] neden O(1)'dir?

Giriş

Öğrenme Çıktıları

Belleği okumak

Dizi öğelerinin ardışık yerleşimini ve adres hesabını açıklamak.

Kayıt kurmak

İlişkili alanları struct ile tek bir tür altında toplamak.

Dinamik dizi kullanmak

malloc, realloc ve free yaşam döngüsünü güvenle yönetmek.

Gösterim seçmek

Yoğun ve seyrek matris gösterimlerini karşılaştırmak.

Temel Kavramlar

Dizinin gücü: sabit zamanda erişim

Başlangıç adresi ve öğe boyutu bilindiğinde herhangi bir indis doğrudan hesaplanabilir.

Ardışıklık

Öğeler bellekte yan yanadır; önbellek yerelliği yüksektir.

Sabit boyut

Yer ayrıldıktan sonra kapasite kendiliğinden büyümez.

Rastgele erişim

a[i] adresi başlangıç + i × sizeof(T) ile bulunur.

Kaydırma maliyeti

Araya ekleme ve silme, sonraki öğeleri taşımayı gerektirir.

Temel Kavramlar

Kavram Haritası

1Dizi
2Adres hesabı
3struct
4Dinamik bellek
5Matris
6Seyrek matris
Başlangıç adresi ve öğe boyutu bilindiğinde herhangi bir indis doğrudan hesaplanabilir.

Gösterim

Bellekte bir int dizisi

0121722534418

&a[3] = başlangıç + 3 × sizeof(int)

Ardışık yerleşim hızlı erişim sağlar; ancak kapasite değişimi yeni bir blok ayırıp kopyalama gerektirebilir.

C ile Gerçekleştirim

Dizi ile kayıtları birleştirmek

typedef struct {
    int no;
    char ad[32];
    double ortalama;
} Ogrenci;

Ogrenci sinif[40];
Tür tanımı veri yapısının bellekteki biçimini; yordamlar ise bu yapı üzerindeki davranışı kurar.

C ile Gerçekleştirim

C'de Bellek ve Sahiplik

Sahip kim?

Ayrılan belleği hangi yapı veya yordamın bırakacağını baştan belirle.

Yaşam süresi

Yerel değişken adresini fonksiyon dışına taşırma; dinamik belleği gerektiği kadar yaşat.

Sınırlar

Boyut, kapasite ve geçerli indisleri her işlemde koru.

Boş durum

NULL, boş yapı ve tek öğe durumlarını özellikle dizi sınırının dışına çıkmak riskiyle birlikte test et.

Temel İşlemler

Dinamik kapasite büyütme

int *gecici = realloc(dizi, yeni_kapasite * sizeof *dizi);
if (gecici == NULL) {
    /* Eski dizi hâlâ geçerli. */
    hata_isle();
}
dizi = gecici;
kapasite = yeni_kapasite;
Kod örnekleri C99/C11 uyumlu olacak biçimde küçük ve tek sorumluluklu tutulmuştur.

Temel İşlemler

Kodu Okurken

Ön koşul

a[i] neden O(1)'dir?

Değişmez

Her adımda ardışıklık kuralı korunuyor mu?

Son koşul

İlişkili alanları struct ile tek bir tür altında toplamak.

Hata yolu

realloc sonucunu doğrudan eski göstergeye yazmak

Adım Adım

Araya ekleme: 9 değerini indis 2'ye koy

Başlangıç

[12, 7, 25, 4, 18], boyut = 5

Yer aç

18, 4 ve 25 birer hücre sağa kaydırılır.

Yaz

a[2] = 9 yapılır.

Bitir

[12, 7, 9, 25, 4, 18], boyut = 6; maliyet O(n).

Sınıf Notu

Dersten Sesler

“Eğer performansı artıracaksa, makul ölçüde olmak kaydıyla fazladan bellek kullanmakta sakınca yok.”
“Dizi aç, n. indis n. üssü tutsun. SAKIN HA! Önce verinin gerçekten yoğun olup olmadığına bak.”

Notlardaki sınıf içi anlatımdan, yazım ve uzunluk bakımından sunuma uyarlanmıştır.

Analiz

Karmaşıklık Özeti

İşlemZamanEk bellek
a[i] erişimiO(1)O(1)
Sonda ekleme (boş yer)O(1)O(1)
Araya eklemeO(n)O(1)
Doğrusal aramaO(n)O(1)
m×n matris taramaO(mn)O(1)

n: öğe sayısı · h: yükseklik · V: düğüm sayısı · E: kenar sayısı

Tasarım Kararı

Hangi Durumda Hangisi?

Dizi

Boyut biliniyor ve indisle erişim baskınsa.

Dinamik dizi

Okuma yoğun, sona ekleme sık ve kapasite büyüyebiliyorsa.

struct dizisi

Aynı türden kayıtlar tablo gibi işlenecekse.

Seyrek gösterim

Matrisin büyük bölümü sıfırsa yalnız dolu hücreleri saklamak için.

Dikkat

Sık Yapılan Hatalar

1Dizi sınırının dışına çıkmak
2realloc sonucunu doğrudan eski göstergeye yazmak
3sizeof(T*) ile sizeof(T) değerlerini karıştırmak
4free sonrasında göstergeyi kullanmak

Alıştırmalar

Kendini Sına

  1. a[i] neden O(1)'dir?
  2. Kapasite dolu dinamik dizi nasıl büyütülür?
  3. struct ile paralel diziler arasında ne fark vardır?
  4. Satır-major bir matriste a[i][j] adresi hangi bilgilere bağlıdır?
  5. Seyrek matris ne zaman bellek kazandırır?
Cevapları göster
  1. Adres doğrudan aritmetik ile hesaplanır.
  2. Daha büyük blok ayrılır; öğeler kopyalanır; eski blok bırakılır.
  3. struct bir kayda ait alanları birlikte tutar ve tutarlılığı artırır.
  4. Başlangıç adresi, sütun sayısı, i, j ve öğe boyutu.
  5. Sıfır olmayan öğe sayısı toplam hücre sayısından çok küçükse.

Uygulama

Mini Laboratuvar

1 · Çiz

a[i] neden O(1)'dir?

2 · Kodla

struct ile paralel diziler arasında ne fark vardır?

3 · Ölç

Seyrek matris ne zaman bellek kazandırır?

Teslim: küçük bir C modülü, üç uç test ve zaman/bellek karmaşıklığı tablosu.

Özet

Bölüm Özeti

Hızlı erişim

İndisle erişim O(1).

Pahalı kaydırma

Araya ekleme ve silme O(n).

Bellek disiplini

Her ayırmanın bir sahibi ve bırakma noktası olmalı.

Özet

Kaynaklar ve Devam

Son

Bölüm 2: Diziler ve Yapılar
Ders planına dön
1 / 1 C ile Veri Yapıları