Sıralama ve arama: Python ile anlaşılır algoritma örnekleri

Temel Algoritmalar

Sıralama ve arama: Python ile anlaşılır algoritma örnekleri

Temel Algoritmalar
5 dk okuma süresi
Python'da sıralama ve arama algoritmalarının temellerini örneklerle, performans notları ve pratik ipuçlarıyla öğrenin.
Sıralama ve arama: Python ile anlaşılır algoritma örnekleri

Giriş

Sıralama ve arama algoritmaları, veriyi düzenleme ve hızlı erişim sağlayabilmek için programlamanın temel taşlarındandır. Bu yazıda Python'da sık kullanılan sıralama yöntemlerini (Kabarcık, Seçmeli, Eklemeli) ve Python'un yerleşik yaklaşımı ile arama algoritmalarını (Doğrusal ve İkili arama) adım adım göreceksiniz. Temel amaç: nasıl çalıştıklarını anlamak, hangi durumda hangisini tercih edeceğinize dair pratik kararlar alabilmektir.

Python'un yerleşik sıralama davranışı ve önerileri için resmi belgeye bakabilirsiniz: Sıralama NASIL YAPILIR — Python 3.11. Google'ın eğitim içeriği de pratik örnekler sunar: Python Sıralama | Google Developers. Arama algoritmaları ve veri yapıları hakkında açıklayıcı bir özet için bkz.: Python ile Veri Yapıları ve Algoritmalar — Osman Bayrak.

Sıralama algoritmalarına hızlı bakış

Aşağıda sık karşılaşılan yöntemlerin kısa karşılaştırması yer alıyor:

  • Yerleşik Python sıralaması (Timsort): Python'un sorted() ve list.sort() fonksiyonları adaptif, stabil bir algoritma kullanır; genel kullanım için önerilir. Ayrıntılar için Python belgelerine bakın.
  • Kabarcık Sıralama (Bubble Sort): Basit, ancak büyük veri için verimsiz (O(n²) zaman karmaşıklığı). Genellikle öğrenme amaçlıdır.
  • Seçmeli Sıralama (Selection Sort): Her adımda en küçük/ en büyük öğeyi seçip yer değiştirir; kabarcık gibi O(n²) karmaşıklığa sahiptir.
  • Eklemeli Sıralama (Insertion Sort): Küçük veya neredeyse sıralı veri setlerinde etkili; ortalama O(n²) ama küçük n'lerde hızlıdır.

Python'un yerleşik sıralama fonksiyonları çoğu durumda en iyi tercih olacaktır; özel durumlar ve eğitim amaçlı açıklamalar için klasik algoritmaları incelemek yararlıdır (Python docs, Google Developers).

Yerleşik sıralama: Timsort ve kullanımı

Python'daki sorted() ve list.sort() fonksiyonları, kararlı (stable) ve adaptif bir algoritma uygular. Genel tavsiye: veri tipleri karışıksa veya performans kritik değilse yerleşik fonksiyonları kullanın; bu fonksiyonlar key ve reverse argümanlarıyla esnek davranır.

nums = [5, 2, 9, 1]
sorted_nums = sorted(nums) # yeni liste döner
nums.sort(reverse=True) # aynı listeyi tersine sıralar

Ayrıca karmaşık nesneler için key parametresi kullanarak anahtar fonksiyona göre sıralama yapabilirsiniz. (Detaylar: Python Sıralama Rehberi.)

Kabarcık (Bubble) Sıralama

Algoritma: Listenin sonuna doğru büyük elemanları "kabarcık" gibi iteratif olarak itersiniz. Öğrenmesi kolaydır, ancak verimlilik düşük olduğu için üretim kodlarında nadiren tercih edilir.

def bubble_sort(a):
n = len(a)
for i in range(n):
for j in range(0, n - i - 1):
if a[j] > a[j + 1]:
a[j], a[j + 1] = a[j + 1], a[j]

Zaman karmaşıklığı: tipik olarak O(n²). Eğitim için yararlıdır; gerçek veri kümeleri için yerleşik sıralamalar daha uygundur.

Seçmeli (Selection) Sıralama

Algoritma: Her iterasyonda kalan kısmın en küçük öğesini bulup ilk pozisyonla takas edersiniz.

def selection_sort(a):
n = len(a)
for i in range(n):
min_idx = i
for j in range(i+1, n):
if a[j] < a[min_idx]:
min_idx = j
a[i], a[min_idx] = a[min_idx], a[i]

Seçmeli sıralama da O(n²) zaman alır; sabit bellek kullanımı avantajıdır.

Eklemeli (Insertion) Sıralama

Algoritma: Listeyi soldan sağa tarayıp her öğeyi uygun konuma "yerleştirirsiniz". Veri kısmen sıralıysa oldukça etkilidir.

def insertion_sort(a):
for i in range(1, len(a)):
key = a[i]
j = i - 1
while j >= 0 and a[j] > key:
a[j + 1] = a[j]
j -= 1
a[j + 1] = key

Küçük veya neredeyse sıralı listeler için insertion sort pratik bir seçim olabilir.


Arama algoritmaları

Arama yaparken öncelikle verinin sıralı olup olmadığına bakın. Sıralı veri, ikili arama gibi hızlı yöntemlere izin verir.

Doğrusal (Linear) Arama

Her öğeyi sırayla kontrol eden basit yöntem. Sıralama gerektirmez, ancak büyük listelerde yavaştır.

def linear_search(a, target):
for i, v in enumerate(a):
if v == target:
return i
return -1

Zaman karmaşıklığı: O(n). Küçük boyutlu veya sıralı olmayan veri için uygundur. (Genel açıklamalar için bkz.: Osman Bayrak – Veri Yapıları ve Algoritmalar.)

İkili (Binary) Arama

Sıralı bir listede çalışır; aranan aralıktaki öğe her adımda yarıya indirilir, bu yüzden O(log n) zaman alır. Python'da kendi implementasyonunuzu yazabilir veya bisect modülünü kullanabilirsiniz.

def binary_search(a, target):
lo = 0
hi = len(a) - 1
while lo <= hi:
mid = (lo + hi) // 2
if a[mid] == target:
return mid
elif a[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1

Alternatif olarak:

import bisect
i = bisect.bisect_left(sorted_list, target)
if i < len(sorted_list) and sorted_list[i] == target:
# bulundu

Pratik örnek: Sıralama sonra arama

Problem: Karışık bir sayı listesinde bir değerin olup olmadığını hızlıca kontrol etmek istiyorsunuz. Adımlar:

  1. Yerleşik sorted() ile listeyi sırala (veya .sort() kullanarak yerinde sırala).
  2. İkili arama ile arama yap (kendi fonksiyonun veya bisect).

arr = [7, 2, 5, 10, 3]
arr.sort()
idx = binary_search(arr, 5) # ya da bisect kullan

Bu yaklaşım, çok sayıda arama yapılacağı durumlarda avantajlıdır: bir kez sıralayıp sonra hızlı arama yaparsınız. Python'un yerleşik sıralaması genelde başlangıç maliyetini dengeleyecek hızdadır (Python docs).

Performans ölçümü

Basit zaman ölçümü için time.perf_counter() veya timeit kullanılabilir. Gerçek veriler, verinin dağılımı ve çalışma ortamı sonuçları etkiler; bu yüzden kendi veriniz üzerinde test yapmak en güvenilir yoldur.

import time
t0 = time.perf_counter()
sorted_list = sorted(big_list)
t1 = time.perf_counter()
print('sort time', t1 - t0)

Pratik ipuçları ve seçim rehberi

  • Genel amaçlı sıralama için sorted() veya list.sort() kullanın; bunlar Timsort tabanlıdır ve çoğu duruma uygundur (Python docs).
  • Küçük veya neredeyse sıralı veri için insertion sort etkili olabilir.
  • Büyük veri setlerinde O(n log n) olan yerleşik sıralamalar tercih edilir.
  • Eğer veriniz sıralıysa, binary search ile O(log n) arama yapabilirsiniz; aksi halde önce sıralama gerekir veya linear search tercih edilir.
  • Sıralama sırasında karmaşık anahtarlar için key argümanını kullanın (ör. tuple'lar, dict değerleri vb.).

Kaynaklar ve ileri okuma

Kontrol listesi (Quick checklist)

  • Veri sıralı mı? → Evet: ikili arama; Hayır: sıralama veya doğrusal arama.
  • Aynı anahtara göre sıralama gerekiyor mu? → key ve stabil sıralama kullanın.
  • Performans kritik mi? → Yerleşik sort genelde en iyi başlangıç noktasıdır.