Temel Veri Yapıları ve Uygulamaları: Örnek Kodlarla Anlatım

Algoritma ve Veri Yapıları

Temel Veri Yapıları ve Uygulamaları: Örnek Kodlarla Anlatım

Bu makale dizi, bağlı liste, yığın ve kuyruk gibi temel veri yapılarını tanımlar, Python ile örnek uygulamalar gösterir ve öğrenme/performans önerileri sunar.
Temel Veri Yapıları ve Uygulamaları: Örnek Kodlarla Anlatım

Giriş

Veri yapıları, veriyi organize etme ve üzerinde etkili işlemler yapma yöntemleridir. Bu makalede dizi, bağlı liste, yığın ve kuyruk gibi temel veri yapılarını tanımlayacağız, Python ile örnek uygulamalar göstereceğiz ve performans ile uygulama önerileri sunacağız. Başlangıç için Arslan Engin'in rehberi faydalı tanımlar ve örnekler içerir: Veri Yapıları 1. Veri yapılarını öğrenmenin yazılım mühendisliğindeki rolü ve uygulama alanları için üniversite ders notlarına bakabilirsiniz: Harran Üniversitesi - Veri Yapıları ve Algoritmalar.

Neden öğrenmeliyiz?

Doğru veri yapısı seçimi, bir uygulamanın hızını ve bellek kullanımını doğrudan etkiler. Veri yapılarını bilmek; veri erişimi, arama, sıralama ve gerçek zamanlı işleme gibi görevlerde daha iyi tasarım kararları almanızı sağlar. Uygulama alanları arasında veri tabanları, ağ uygulamaları, sistem yazılımları ve eğitim amaçlı algoritma problemleri sayılabilir (ayrıntılar için Harran Üniversitesi).

Temel Veri Yapıları: Tanımlar ve Kullanım Örnekleri

Dizi (Array)

Dizi, sıralı ve indekslenebilir eleman koleksiyonudur. Sabit bir indeks ile doğrudan erişim sağlanır; bu nedenle rastgele erişim O(1) zaman alır. Dinamik dillerde (ör. Python) dizi benzeri yapı "list" olarak bulunur ve arka planda dinamik dizi mantığıyla çalışır. Diziler sabit uzunluklu veya dinamik olabilir; uygulama ihtiyacına göre seçim yapın. Daha fazla tanım için Arslan Engin kaynağına bakın.

Bağlantılı Liste (Linked List)

Bağlantılı listede her eleman (düğüm) bir değeri ve bir sonraki düğüme işaret eden referansı tutar. Düğümler bellekte dağınık yerlerde olabilir; araya ekleme ve silme işlemleri düğüm referansları güncellenerek O(1) yapılabilir (başta veya bilinen düğümde). Ancak rastgele index ile erişim O(n) zaman alır.

Yığın (Stack)

Yığın LIFO (Last-In, First-Out) prensibiyle çalışır. Son eklenen öğe ilk çıkar. Geri alma/ileri alma mekanizmaları, fonksiyon çağrı yönetimi gibi senaryolarda sık kullanılır.

Kuyruk (Queue)

Kuyruk FIFO (First-In, First-Out) prensibiyle çalışır. İşlem sıraları, görev kuyruğu ve genişlik öncelikli arama (BFS) gibi durumlarda kullanışlıdır. Python'da verimli kuyruk için collections.deque önerilir.


Örnek Kodlar (Python)

Aşağıdaki örnekler eğitim amaçlıdır. Kodları çalıştırmadan önce kendi ortamınızda test edin ve sınır durumları ekleyin.

Dizi (Python list) örnekleri

Oluşturma ve temel işlemler
arr = [10, 20, 30, 40]
arr.append(50) # sona ekleme
arr.insert(2, 25) # index 2'ye ekleme
val = arr.pop() # sondan silme ve değer döndürme
for x in arr:
print(x)

Tek yönlü bağlı liste (basit uygulama)

Basit sınıflarla bağlı liste
class Node:
def __init__(self, value):
self.value = value
self.next = None

class LinkedList:
def __init__(self):
self.head = None

def insert_at_head(self, value):
node = Node(value)
node.next = self.head
self.head = node

def insert_at_tail(self, value):
node = Node(value)
if self.head is None:
self.head = node
return
current = self.head
while current.next is not None:
current = current.next
current.next = node

def delete_value(self, value):
current = self.head
prev = None
while current is not None:
if current.value == value:
if prev is None:
self.head = current.next
else:
prev.next = current.next
return True
prev = current
current = current.next
return False

def iterate(self):
current = self.head
while current is not None:
print(current.value)
current = current.next

Kullanım örneği
ll = LinkedList()
ll.insert_at_head(3)
ll.insert_at_tail(5)
ll.insert_at_head(1)
ll.iterate() # 1, 3, 5

Yığın (Stack) örneği

Basit Stack sınıfı (liste kullanarak)
class Stack:
def __init__(self):
self.items = []

def push(self, value):
self.items.append(value)

def pop(self):
if not self.items:
return None
return self.items.pop()

def peek(self):
if not self.items:
return None
return self.items[-1]

Kuyruk (Queue) örneği

collections.deque ile verimli kuyruk
from collections import deque
q = deque()
q.append('a') # enqueue
q.append('b')
item = q.popleft() # dequeue (O(1))
print(item)


Temel Algoritma Örnekleri

Doğrusal Arama (Linear Search) — Dizi

Basit bir arama örneği:

def linear_search(arr, target):
for i in range(len(arr)):
if arr[i] == target:
return i
return -1

Bağlantılı Listeyi Ters Çevirme (Iteratif)

Bağlantılı listeyi yerinde ters çevirmek sık kullanılan bir alıştırmadır. Mantık üç gösterge kullanır: prev, current ve next. Aşağıdaki işlem düğümlerin yönlerini değiştirir.

def reverse_linked_list(head):
prev = None
current = head
while current is not None:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev # yeni head

Bu işlem O(n) zaman ve O(1) ek alan gerektirir.


Performans (Zaman ve Alan Karmaşıklıkları)

Aşağıdaki tablo yaygın işlemler için kaba Big-O değerlerini gösterir. Gerçek etkiler kullanılan dilin ve implementasyonun detaylarına bağlıdır; örneğin Python'da list append amortize O(1) sağlar.

Yapı Erişim Arama Ekleme Silme
Dizi (dynamic array) O(1) O(n) O(1) amortize (son) O(n)
Bağlantılı Liste O(n) O(n) O(1) (başta) O(1) (düğüm biliniyorsa)
Yığın (Stack) O(n) O(1) O(1)
Kuyruk (Queue, deque) O(n) O(1) O(1)

Pratik Öneriler ve Çalışma Planı

  • Her veri yapısını önce elle (kağıt üzerinde) çizerek kavrayın: düğümlerin bağlantısını ve sınır durumlarını (boş, tek elemanlı) düşünün.
  • Kendi implementasyonunuzu yazın, ardından hazır kütüphane sürümleriyle karşılaştırın (örneğin deque vs list).
  • Basit birim testleri yazın: boş giriş, tek eleman, tekrar eden elemanlar, büyük girdiler gibi durumları test edin.
  • Pratik proje fikirleri: küçük bir görev kuyruğu, geri alma (undo) mekanizması, log dosyası analiz aracı.
  • İleri adım olarak ağaçlar ve grafikler gibi yapıları inceleyin; bunlar veri yapıları dünyasının doğal ilerlemesidir.

Kaynaklar ve İleri Okuma

Özet

Bu makalede dizi, bağlı liste, yığın ve kuyruk gibi temel veri yapılarını tanımladık, Python örnekleri sunduk ve performans açısından karşılaştırdık. Temel amaç, hangi yapıların hangi durumlarda daha uygun olabileceğini anlamanızdır. Kendi implementasyonlarınızı yazıp test ederek öğrenmeyi derinleştirmeniz tavsiye edilir.

Sıkça Sorulan Sorular (SSS)

S1: Hangi programlama diliyle başlamak en iyisidir?
Başlangıç için Python tavsiye edilir; sözdizimi basittir ve veri yapılarıyla deney yapmak hızlı sonuç verir. Temel kavramlar daha sonra C++, Java veya diğer dillere taşınabilir.

S2: Bağlantılı listeyi neden kullanmalıyım?
Sık sık araya ekleme/silme yapılıyorsa ve rastgele erişim gerekli değilse, bağlı liste uygun olabilir. Bellekte ardışık depolama zorunlu değilse avantaj sağlar.

S3: Üretim kodunda hangi ek önlemler gereklidir?
Eğimli durum kontrolleri, hata yakalama, sınır testi ve performans profil çalışmaları eklenmelidir. Örnekler eğitim amaçlıdır; üretim sistemi gereksinimlerine göre uyarlama yapın.

S4: Öğrenme kaynakları nelerdir?
Hem ücretsiz çevrimiçi kurslar hem de üniversite ders notları faydalıdır. Başlangıç için WIZAPE ve Arslan Engin kaynaklarına göz atabilirsiniz.