Bölüm 6: Sorular

Veri Yapıları · Örnek Sorular
StackList ve ArrayListPriorityQueue ListIterator ve özyinelemeDinamik diziKuyrukDairesel bağlı liste
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Program izleme

Verilen Java kodunu adım adım izleyerek çıktıyı belirlemek.

İç gösterim

Veri yapısının bellekteki durumunu işlem adımlarıyla ilişkilendirmek.

API davranışı

Koleksiyon metotlarının yan etkilerini ve dönüş değerlerini yorumlamak.

Hata bulma

Sınır durumlarını ve yaygın kullanım hatalarını fark etmek.

Giriş

Bu Sunum Nasıl Kullanılır?

1 · Kodu okuyunHer slaytta kısa bir Java kodu ve bir soru var. Çoğunda soru: "Çıktı nedir?"
2 · Tahmin edinKâğıt üzerinde veri yapısının durumunu adım adım izleyin, çıktıyı yazın.
3 · Kontrol edinCevaplar gizli başlar: "Cevabı göster" kutusunu açın ya da → ile adımları ilerletin.

Sorularda Bölüm 4 (yığın), 5 (kuyruk), 6 (liste) konuları ve Bölüm 8'e giriş niteliğinde PriorityQueue kullanılıyor.

Soru 1 · Yığın

Soru 1: Stack İşlemleri

Programın çıktısı nedir? (İpucu: Stack, Vector'dan türer.)

public static void main(String args[]) {
  Stack<String> stack = new Stack<>();
  stack.push("A");
  stack.push("B");
  stack.push("C");
  System.out.println(stack.pop());
  System.out.println(stack.peek());
  System.out.println(stack.remove("A"));
  System.out.println(stack.pop());
  System.out.println(stack.add("D"));
  System.out.println(stack.remove("B"));
}
A B C ← üst yığın çıktı:

Üç push sonrası durum. Çıktıyı tahmin edin, sonra adımlayın.

A B ← üst yığın çıktı: C

pop() → C (üstteki çıkar)

A B ← üst yığın çıktı: C B

peek() → B (çıkarmaz)

B ← üst yığın çıktı: C B true

remove("A"): Vector metodu, dipteki A silinir → true

yığın çıktı: C B true B

pop() → B; yığın boş

D ← üst yığın çıktı: C B true B true

add("D"): sona (üste) ekler → true

D ← üst yığın çıktı: C B true B true false

remove("B"): B yok → false

Soru 2 · Liste

Soru 2: Diziden Listeye

Programın çıktısı nedir?

public static void main(String[] argv) {
  int[] array = {6, 9, 8};
  List<Integer> list =
          new ArrayList<>();
  list.add(array[0]);
  list.add(array[2]);
  System.out.println(list);
  list.set(1, array[1]);
  list.remove(0);
  System.out.println(list);
}
Cevabı göster
[6, 8]
[9]
  • add(6), add(8) → [6, 8]
  • set(1, 9): indeks 1'deki 8, 9 olur → [6, 9]
  • remove(0): int argüman indekstir → 6 silinir → [9]
  • array değişmez; listeye değerler kopyalandı (kutulanarak).

Soru 3 · Liste

Soru 3: Arama Metotları

Programın çıktısı nedir? Yorum satırı açılsaydı ne olurdu?

public static void main(String[] argv) {
  ArrayList<String> list =
          new ArrayList<>();
  list.add("dog");
  list.add("cat");
  list.add("frog");
  System.out.println(
      list.contains("cat"));
  //System.out.println(
  //    list.hasObject("cat"));
  System.out.println(
      list.indexOf("cat"));
  System.out.println(list.indexOf(1));
}
Cevabı göster
true
1
-1
  • contains("cat") → true.
  • indexOf("cat") → 1 (indeksler 0'dan).
  • indexOf(1) derlenir çünkü parametre Object'tir: 1, Integer'a kutulanır; hiçbir String'e eşit olmadığından → −1. get(1) ile karıştırmayın!
  • hasObject diye bir metot yok → derleme hatası.

Soru 4 · Öncelikli Kuyruk

Soru 4: PriorityQueue

PriorityQueue<String> pq =
        new PriorityQueue<String>();
pq.add("7");
pq.add("4");
System.out.println(pq.peek() + " ");
pq.offer("2");
System.out.println(pq.peek());
pq.add("3");
System.out.println(pq.peek());
pq.offer("1");
System.out.println(pq.peek());
pq.remove("1");
System.out.println(pq.poll() + " ");
System.out.println(pq.remove("2"));
System.out.println(pq);
System.out.println(pq.poll() + " "
        + pq.peek());

Çıktı nedir? println(pq) hangi sırayla yazar?

Cevabı göster
4
2
2
1
2
false
[3, 7, 4]
3 4

En küçük öğe (String sırası) başta. toString sıralı değil, iç yığın (heap) dizisinin sırasını yazar: 2 çekildikten sonra dizi [3, 7, 4] (Bölüm 8).

Soru 4 · Öncelikli Kuyruk

Soru 4: İç Dizinin Adım Adım Durumu

Önceki slaytta tahmin ettiğiniz [3, 7, 4] sırasını doğrulayalım.

Çözüm tablosunu göster
İşlemİç dizi (heap)YazılanAçıklama
add 7, add 4[4, 7]4, ebeveyni 7'den küçük → yukarı çıkar
peek[4, 7]4kök = en küçük
offer 2 → peek[2, 7, 4]22 köke çıkar
add 3 → peek[2, 3, 4, 7]23, 7 ile yer değiştirir
offer 1 → peek[1, 2, 4, 7, 3]11 önce 3, sonra 2 ile yer değiştirir
remove("1")[2, 3, 4, 7]son öğe (3) köke gelir, aşağı iner
poll[3, 7, 4]27 köke gelir, 3 ile yer değiştirir
remove("2")[3, 7, 4]false2 artık yok
poll + peek[4, 7]3 4soldan sağa: önce poll, sonra peek

Soru 5 · Liste

Soru 5: ListIterator ile Özyineleme

Programın çıktısı nedir? fonksiyon genel olarak neyi hesaplar?

int fonksiyon(ListIterator<String> it) {
  if (it.hasNext()) {
    it.next();
    return 1 + fonksiyon(it);
  }
  return 0;
}
public static void main(String args[]) {
  List<String> list = new LinkedList<>();
  list.add("A"); list.add("B");
  list.add("C");
  ListIterator<String> it =
          list.listIterator();
  System.out.println(
      (new Ornek5()).fonksiyon(it));
}
Cevabı göster
3
  • Her çağrı bir öğe atlar ve 1 ekler: 1 + (1 + (1 + 0)) = 3.
  • Genel olarak: iterator'ın önünde kalan öğe sayısını sayar. İterator paylaşıldığından, çağrı sonrası imleç sondadır; ikinci çağrı 0 döndürür.
  • fonksiyon statik olmadığından main onu bir Ornek5 nesnesi üzerinden çağırır.
  • Özyineleme derinliği n: çok uzun listede StackOverflowError riski.

Soru 6 · Yığın

Soru 6: Yığın ve Mod Alma

Programın çıktısı nedir? Kod genel olarak ne yapar?

public static void main(String[] args) {
  Stack<Integer> stack =
          new Stack<Integer>();
  int n = 12;
  while (n > 0) {
    stack.push(n % 2);
    n /= 2;
  }
  while (!stack.isEmpty())
    System.out.print(stack.pop());
}
yığın n = 12

Başlangıç: n = 12, yığın boş. Çıktıyı tahmin edin.

0 ← üst yığın n = 6

12 % 2 = 0 → push(0); n = 6

0 0 ← üst yığın n = 3

6 % 2 = 0 → push(0); n = 3

0 0 1 ← üst yığın n = 1

3 % 2 = 1 → push(1); n = 1

0 0 1 1 ← üst yığın n = 0

1 % 2 = 1 → push(1); n = 0, döngü biter

yığın n = 0 çıktı:1100

Yığın boşaltılır: 1, 1, 0, 0 → 1100 = 12'nin ikili gösterimi

Soru 7 · Dinamik Dizi

Soru 7: Büyüyüp Küçülen Dizi

Bu sınıf, N öğeyi capacity boyutlu items dizisinde tutuyor. Doluluk oranı hangi aralıkta kalır? Kodda hata var mı?

private void shrinkStretch() {
  if (N < capacity / 4) {
    capacity /= 2;
    items = Arrays.copyOf(items, capacity);
  } else if (N > capacity / 2) {
    capacity *= 2;
    items = Arrays.copyOf(items, capacity);
  }
}
public void removeItem() {
  items[N--] = null;  shrinkStretch();
}
public void addItem(E e) {
  items[N++] = e;  shrinkStretch();
}
Cevabı göster
  • Yarıdan fazla dolunca kapasite ikiye katlanır, dörtte birin altına inince yarıya iner → doluluk yaklaşık ¼ ile ½ arasında kalır.
  • Kopyalama O(n) ama seyrek: addItem/removeItem amortize O(1).
  • Hata: items[N--] = null son öğeyi değil, ondan sonraki boş hücreyi siler; son öğe dizide kalır. Doğrusu items[--N] = null;
  • Boş dizide removeItem için kontrol yok (N negatif olur).

Soru 8 · Kuyruk

Soru 8: Kuyruktan Yığına, Yığından Kuyruğa

Programın çıktısı nedir? İşlemin sonunda kuyruğa ne olmuştur?

Stack<String> s = new Stack<>();
Queue<String> q = new LinkedList<>();
q.offer("a"); q.offer("b");
q.offer("c"); q.offer("d");
while (!q.isEmpty())
    s.push(q.poll());
System.out.println("s: " + s
        + " --- q: " + q);
while (!s.isEmpty())
    q.offer(s.pop());
System.out.println("s: " + s
        + " --- q: " + q);
s (yığın) a b c d önarka q (kuyruk)

Başlangıç: q = [a, b, c, d]. Çıktıyı tahmin edin.

a b c d ← üst s (yığın) önarka q (kuyruk) s: [a, b, c, d] --- q: []

q'dan sırayla çıkan a, b, c, d yığına itilir: üstte d

s (yığın) d c b a önarka q (kuyruk) s: [a, b, c, d] --- q: [] s: [] --- q: [d, c, b, a]

Yığından çıkan d, c, b, a kuyruğa eklenir → kuyruk tersine döndü

Soru 9 · Bağlı Liste

Soru 9: Bu Liste Nerede Biter?

Programın çıktısı nedir? fonksiyon neyi test eder?

public static void main(String[] args) {
  Node head = new Node(1);
  head.next = new Node(2);
  head.next.next = new Node(3);
  head.next.next.next = new Node(4);
  head.next.next.next.next = head;
  System.out.println(
      fonksiyon(head, head.next));
}
static int fonksiyon(Node head, Node curr) {
  if (head == null) return 1;
  if (curr == null) return 0;
  if (head == curr) return 1;
  return fonksiyon(head, curr.next);
}
1 2 3 4 head head.next
Cevabı göster
1
  • curr 2 → 3 → 4 → 1 diye ilerler; 1 = head olunca 1 döner.
  • Fonksiyon, listenin dairesel olup olmadığını (sondan head'e dönüp dönmediğini) test eder: null'a ulaşırsa 0.
  • Boş liste (head null) de 1 sayılıyor. Döngü head'e değil ortadaki bir düğüme dönüyorsa özyineleme hiç bitmez.

Özet

Sorulardan Çıkan Dersler

SoruKonuAkılda kalsın
1StackStack bir Vector'dır: remove(o), add(e) da çalışır
2ListList<Integer>'da remove(int) indeks siler
3ListindexOf(Object) her türü kabul eder, bulamazsa −1
4PriorityQueuepeek/poll en küçüğü verir; toString heap sırasıdır
5ListIteratorPaylaşılan iterator'ın imleci çağrılar arasında korunur
6StackKalanları yığına itip çekmek → ikili gösterim
7Dinamik diziKatla / yarıla → amortize O(1); --N ile N-- farkı
8Kuyruk + yığınYığından geçirmek sırayı tersine çevirir
9Bağlı listeDairesellik testi: head'e geri dönülüyor mu?

Özet

Kaynaklar

  • Oracle, Java SE 17 List, ListIterator, Stack ve PriorityQueue API belgeleri.
  • Goodrich, Tamassia ve Goldwasser, Data Structures and Algorithms in Java, 6. baskı, 2014.
  • Sorular, 2-6. bölümlerde ele alınan kavram ve örnekleri temel alır.

Son

Bölüm 6: Sorular
Sonraki bölüm: Ağaçlar
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.

← → veya boşluk ile gezinin · F: tam ekran · Home/End: ilk/son slayt