Bölüm 7: Kuyruklar
Klasik Soru · Kuyruk ADT
Soru 1: Aynı Girdi, İki Yapı
y bir yığın, k bir kuyruktur (ikisi de boş ve yeterince büyük). Program ne yazdırır?
for (i = 1; i <= 4; i++) { push(&y, i); ekle(&k, i * i); } pop(&y, &a); al(&k, &b); printf("%d %d\n", a, b); push(&y, b); ekle(&k, a); while (pop(&y, &a)) printf("%d ", a); printf("| "); while (al(&k, &b)) printf("%d ", b);
Cevabı göster
Çıktı:
4 1 1 3 2 1 | 4 9 16 4
- Döngüden sonra yığın (alttan üste) 1 2 3 4, kuyruk (önden arkaya) 1 4 9 16'dır.
- pop en son ekleneni (4), al en önce ekleneni (1) verir:
4 1. - 1 yığının üstüne, 4 kuyruğun arkasına girer. Yığın: 1 2 3 1 → üstten boşalır: 1 3 2 1. Kuyruk: 4 9 16 4 → önden boşalır.
Çoktan Seçmeli · Doğrusal Kuyruk
Soru 2: Doğrusal Kuyrukta Sayım
Dizi ile doğrusal kuyrukta on ilk öğenin bir öncesini, arka son öğeyi gösteriyor; MAX_QUEUE_SIZE = 8, on = 2, arka = 6. Kuyrukta kaç öğe vardır ve kuyruk_dolu çağrılmadan önce en çok kaç ekleme yapılabilir?
A: Öğe sayısı arka − on = 4: indis 3, 4, 5, 6. Ekleme yalnız arkadan yapılır: arka 7'ye çıkınca arka >= MAX − 1 sağlanır ve sonraki ekleme “dolu” sayılır. Öndeki 0, 1, 2 hücreleri boş olduğu hâlde kullanılamaz (sahte doluluk). C seçeneği bu boş hücreleri de sayar.
Klasik Soru · Dairesel Kuyruk
Soru 3: Önce İlerletip Sonra Denetlemek
MAX = 4, başta on = arka = 0. Sırayla 1, 2, 3, 4 eklenmeye çalışılıyor, sonra bir kuyruk_al ve ardından kuyruk_ekle(on, &arka, 9) çağrılıyor. Ne olur? Hata nerededir?
bool kuyruk_ekle(int on, int *arka, int x) { *arka = (*arka + 1) % MAX; if (on == *arka) return false; /* dolu */ kuyruk[*arka] = x; return true; }
Cevabı göster
- 1, 2, 3 indis 1, 2, 3'e yazılır. 4 için
*arkaönce 0'a ilerler, 0 == on olduğundan false döner; amaarka0'da kalır. - Artık
on == arka: kuyruk boş görünür.kuyruk_alfalse döndürür; 1, 2, 3 kaybolmuştur. - 9 indis 1'e yazılır (1'in üzerine) ve kuyruk tek öğeli görünür.
Düzeltme: yeni konum geçici değişkende denenir, yalnız yer varsa *arka güncellenir:
int yeni = (*arka + 1) % MAX; if (yeni == on) return false; *arka = yeni; kuyruk[yeni] = x;
Adım Adım Çalıştırma · Dairesel Kuyruk
Soru 4: Ortadan Başlayan Dairesel Kuyruk
Güvenli dairesel kuyrukta MAX = 4 ve başta on = arka = 2. Sırayla ekle 10, 20, 30, 40; al; ekle 40; al; al yapılıyor. Hangi ekleme reddedilir, alınanlar nelerdir?
MAX = 4 ve başlangıç on = arka = 2: boş kuyruk her indiste başlayabilir.
yeni = 3 ≠ on → arka = 3, kuyruk[3] = 10.
yeni = (3 + 1) % 4 = 0: sarma. kuyruk[0] = 20.
yeni = 1 → kuyruk[1] = 30. Üç öğe: indis 3, 0, 1.
yeni = 2 == on → dolu, false. arka değişmez; 4 hücrede en çok 3 öğe.
on = 3, *x = kuyruk[3] = 10: ilk eklenen ilk çıkar.
Yeniden ekle(40): yeni = 2 ≠ on (3) → kuyruk[2] = 40.
on = (3 + 1) % 4 = 0, *x = 20.
on = 1, *x = 30. Kuyrukta yalnız 40 kaldı: (2 − 1 + 4) % 4 = 1 öğe.
bool ekle(int on, int *arka, int x) { int yeni = (*arka + 1) % MAX; if (yeni == on) return false; *arka = yeni; kuyruk[yeni] = x; return true; } bool al(int *on, int arka, int *x) { if (*on == arka) return false; *on = (*on + 1) % MAX; *x = kuyruk[*on]; return true; }
Çoktan Seçmeli · Dairesel Kuyruk
Soru 5: Sarmalı Kuyrukta Öğe Sayısı
Bir hücre boş bırakılan dairesel kuyrukta MAX = 8, on = 5, arka = 2. Kuyrukta kaç öğe vardır ve hangi indislerdedir (önden arkaya)?
B: (arka − on + MAX) % MAX = (2 − 5 + 8) % 8 = 5. on ilk öğenin bir öncesini gösterdiği için öğeler on + 1'den başlar: 6, 7, sarma, 0, 1, 2. C seçeneği on'u ilk öğe sanır; A ise arka − on'un mutlak değerini alır.
Çoktan Seçmeli · Dairesel Kuyruk
Soru 6: C'de Negatif Kalan
Öğe sayısını bulmak için printf("%d", (arka - on) % MAX); yazılmıştır. MAX = 8, on = 5, arka = 2 iken ne yazdırılır?
C: C'de % işlecinin sonucu bölünenin işaretini alır: −3 % 8 = −3 (ölçüldü). Matematikteki mod 5 verirdi; −5 ise on − arka'nın sonucudur; C'de doğru sonuç için (arka - on + MAX) % MAX yazılır. Deque'de geri adım (on - 1 + KAP) % KAP da bu yüzden böyledir.
Adım Adım Çalıştırma · Dairesel Kuyruk
Soru 7: Bayrakla Dolu/Boş Ayrımı
Bayraklı dairesel kuyrukta KAP = 3. Sırayla ekle 1, 2, 3, 4; al; ekle 4; dört kez al yapılıyor. on == arka durumu ne zaman dolu, ne zaman boş anlamına gelir?
KAP = 3, on = arka = 0, son_ekle = false: boş.
ekle(1): veri[1] = 1, bayrak ekle.
ekle(2): veri[2] = 2.
ekle(3): arka sarılıp 0 olur, on == arka. Bayrak “ekle” olduğu için bu durum doludur: 3 hücrenin 3'ü dolu.
ekle(4): on == arka ve son_ekle → false.
al: on = 1, *x = 1; bayrak “al”.
ekle(4): veri[1] = 4. Yine on == arka ve bayrak ekle: dolu.
al: *x = 2.
al: *x = 3.
al: *x = 4. on == arka ama bayrak “al”: bu kez boş. Sonraki al false döner.
bool ekle(Kuyruk *k, int x) { if (k->on == k->arka && k->son_ekle) return false; k->arka = (k->arka + 1) % KAP; k->veri[k->arka] = x; k->son_ekle = true; return true; } bool al(Kuyruk *k, int *x) { if (k->on == k->arka && !k->son_ekle) return false; k->on = (k->on + 1) % KAP; *x = k->veri[k->on]; k->son_ekle = false; return true; }
Klasik Soru · Bağlı Kuyruk
Soru 8: Boş Kuyruğa İlk Ekleme
Bağlı kuyruğun ekleme yordamı aşağıdaki gibi yazılmıştır. Boş kuyrukla (on = arka = NULL) çağrılınca ne olur? Yordamı düzeltin.
bool kuyruk_ekle(dugum **on, dugum **arka, int x) { dugum *yeni = malloc(sizeof *yeni); if (yeni == NULL) return false; yeni->deger = x; yeni->bag = NULL; (*arka)->bag = yeni; *arka = yeni; return true; }
Cevabı göster
Boş kuyrukta *arka NULL'dır; (*arka)->bag NULL işaretçiyi izler ve program çöker. Ayrıca boş kuyruğa ilk eklemede *on da güncellenmelidir; aksi hâlde kuyruk boş görünmeye devam eder.
if (*arka == NULL) *on = yeni; /* boştu */ else (*arka)->bag = yeni; /* sona bağla */ *arka = yeni;
İki durum da O(1)'dir. Sayaçlı testte 3 ekleme ve 3 almada malloc = free.
Çoktan Seçmeli · Bağlı Kuyruk
Soru 9: Uçların Seçimi
Tek yönlü bağlı listeyle kurulan kuyrukta baş ve son işaretçileri tutuluyor. Ekleme başa, silme sona yapılsaydı hangi işlem O(n) olurdu?
B: Son düğüm silinince yeni son, ondan önceki düğümdür; tek yönlü listede ona ulaşmak için baştan yürünür: O(n). Bu yüzden kuyrukta ekleme sona (arka->bag = yeni), silme baştan (on = on->bag) yapılır; ikisi de O(1).
Adım Adım Çalıştırma · Bağlı Kuyruk
Soru 10: Tek İşaretçili Dairesel Kuyruk
Kuyruk, son düğümün bağı ilk düğüme dönen dairesel bir listeyle ve yalnız arka işaretçisiyle tutuluyor. Ekle 10, 20, 30 ve üç kez al yapılınca bağlar nasıl değişir?
Boş kuyruk: yalnız arka tutulur ve NULL'dır.
İlk düğüm kendini gösterir: yeni->bag = yeni. Tek öğede ön ve arka aynı düğümdür.
20, eski arka ile ön arasına girer: yeni->bag = arka->bag (ön), arka->bag = yeni; sonra arka = 20.
Aynı adımlar: 30 sona girer, bağı yine öne (10) döner. Ekleme O(1).
al: ön = arka->bag (10). Arka'nın bağı önün bağına (20) atlar, 10 bırakılır.
20 alınır. Kalan tek düğüm (30) kendini gösterir.
ön == arka: son öğe gidiyor, *arka = NULL. malloc = free = 3.
bool ekle(dugum **arka, int x) { dugum *yeni = malloc(sizeof *yeni); if (!yeni) return false; yeni->deger = x; if (*arka == NULL) yeni->bag = yeni; else { yeni->bag = (*arka)->bag; (*arka)->bag = yeni; } *arka = yeni; return true; } bool al(dugum **arka, int *x) { if (*arka == NULL) return false; dugum *on = (*arka)->bag; *x = on->deger; if (on == *arka) *arka = NULL; else (*arka)->bag = on->bag; free(on); return true; }
Çoktan Seçmeli · Deque ve Uygulamalar
Soru 11: Deque İşlemleri
KAP = 5 olan dairesel deque boştur (on = 0, sayac = 0). Sırayla sona_ekle(1), basa_ekle(2), sona_ekle(3), bastan_al, basa_ekle(4), sondan_al yapılıyor. Hangi değerler alınır ve deque'de önden arkaya ne kalır?
D: Durumlar: [1] → [2 1] → [2 1 3] → bastan_al 2 → [1 3] → [4 1 3] → sondan_al 3 → [4 1]. basa_ekle on'u bir geri alır: 0'dan (0 − 1 + 5) % 5 = 4'e; sonunda on = 4, sayac = 2 (programla doğrulandı).
Klasik Soru · Deque ve Uygulamalar
Soru 12: Deque'nin Eksik Yarısı
Sayaçlı dairesel deque (veri[KAP], on, sayac) için basa_ekle ve sondan_al hazır. bool sona_ekle(Deque *d, int x) ve bool bastan_al(Deque *d, int *x) yordamlarını yazın.
Cevabı göster
bool sona_ekle(Deque *d, int x) { if (d->sayac == KAP) return false; d->veri[(d->on + d->sayac) % KAP] = x; d->sayac++; return true; } bool bastan_al(Deque *d, int *x) { if (d->sayac == 0) return false; *x = d->veri[d->on]; d->on = (d->on + 1) % KAP; d->sayac--; return true; }
Sona eklerken on değişmez; ilk boş hücre (on + sayac) % KAP'tır. Baştan alırken on bir ileri gider. Dört işlem de O(1); doğru ve kenar durumlar (dolu, boş, sarma) programla denendi.
Klasik Soru · Deque ve Uygulamalar
Soru 13: Round Robin, Q = 3
P0, P1, P2, P3 süreçlerinin kalan işleri 4, 7, 2, 5 birimdir; hepsi t = 0'da bu sırayla kuyruktadır. Zaman dilimi Q = 3 olan round robin benzetiminde süreçler hangi anlarda biter? Toplam kaç kuyruk_al yapılır?
Cevabı göster
| dilim | süreç | aralık | kalan |
|---|---|---|---|
| 1 | P0 | 0–3 | 1 |
| 2 | P1 | 3–6 | 4 |
| 3 | P2 | 6–8 | 0 → biter |
| 4 | P3 | 8–11 | 2 |
| 5 | P0 | 11–12 | 0 → biter |
| 6 | P1 | 12–15 | 1 |
| 7 | P3 | 15–17 | 0 → biter |
| 8 | P1 | 17–18 | 0 → biter |
Bitiş: P2 t = 8, P0 t = 12, P3 t = 17, P1 t = 18. Toplam 8 kuyruk_al (her dilim bir alma); toplam iş 18 birim.
Çoktan Seçmeli · Deque ve Uygulamalar
Soru 14: İki Yığınla Kuyruğun Maliyeti
Kuyruk iki yığınla kuruluyor: ekle giriş yığınına push yapar; al, çıkış yığını boşsa önce girişteki her şeyi çıkışa aktarır. Tek bir al'ın en kötü maliyeti ve boş kuyruktan başlayan n işlemlik bir dizinin toplam maliyeti nedir?
C: Aktarma yapan bir al, girişteki bütün öğeleri taşır: O(n). Ama her öğe en çok bir kez girişe push, bir kez aktarma ve bir kez çıkıştan pop görür; n işlemde toplam O(n), işlem başına amortize O(1). B, her al'ın aktarma yaptığını varsayar.
Çoktan Seçmeli · Deque ve Uygulamalar
Soru 15: Hangi Yapı?
Aşağıdaki işlerden hangisi doğal olarak kuyruk (FIFO) gerektirir?
A: Düzey sırasında bir düğümün çocukları, aynı düzeydeki öteki düğümlerden sonra işlenmelidir: önce giren önce çıkar. Geri alma, parantez denetimi ve çağrı yığını ise “en son açılan ilk kapanır” kuralıyla çalışır: yığın.
Çoktan Seçmeli · Özet
Soru 16: on == arka Ne Demek?
MAX = 6 olan dairesel kuyrukta on = arka = 3 görülüyor. Hangisi doğrudur?
D: Yalnız on ve arka ile 0…MAX öğelik MAX + 1 durum ayırt edilemez. Bir hücre boş bırakma yönteminde dolu koşulu (arka + 1) % MAX == on olduğundan on == arka yalnız boş demektir. Bayraklı yöntemde aynı görüntü son işleme göre dolu ya da boştur.