kjhkjhkj / Karim Idrissi (karim_bakkali) - Profile | Pinterest

Kjhkjhkj

kjhkjhkj

Fıraaaat

kimi seviyosun ya

sevdiğin kişi biliyo mu peki

Nedennn

Herkesin bilmesini istemiyorum

Related users

O zaman kimi sevdin :dd

O

En son kiminle çıktın

Çıkmak önemli değil sevmek önemli

Şevval Mürteza?

Çok severim kendisi de bilir

Öyle zaten doğrusunu dedim :D

Öyle zaten mal :D

Atatürk Anadolu lisesi canım o

Aleyna yakarışik ?

Gözlerin çok guzl diyolar hngi renk

En sevdiğin sohbet konuları nelerdir?

Kim hoşuna gıdiyor ??

Jake

Hoşuna giden gız var mi loo ¿¿¿

En son telefonda kiminle konuştunuz?

Batuhan ÇAĞLAR ?

Aşkımın oğluuuuu :D Delikanlıı <3

Yasin Hakyemez ?

Keskinus desemm

hangi okuldasın

Bu gün planın ne

Aslında çok komiksin yaa ????

Burçlara inanır mısın?

Boran sarikaya ?

Next

Nothing here yet

This user hasn’t answered any questions yet
Ask @AdrianaLimaaaaa

Language: English

Anadolu Edu TR Algoritma

T.C. ANADOLU ÜNİVERSİTESİ YAYINI NO:


AÇIKÖĞRETİM FAKÜLTESİ YAYINI NO:

ALGORİTMALAR VE PROGRAMLAMA

Yazarlar
Arş.Göseafoodplus.info Burcu YILMAZEL (Ünite 1, 2, 3)
seafoodplus.infoç.Dr. Sevcan YILMAZ GÜNDÜZ (Ünite 4, 5)
seafoodplus.infoç.Dr. Alper Kürşat UYSAL (Ünite 6, 7, 8)

Editör
Doç.Dr. Serkan GÜNAL

Bandrol Uygulamasına İlişkin Usul ve Esaslar Hakkında


Yönetmeliğin 5 inci Maddesinin İkinci Fıkrası Çerçevesinde
Bandrol Taşıması Zorunlu Değildir.
Bu kitabın basım, yayım ve satış hakları Anadolu Üniversitesine aittir.
“Uzaktan Öğretim” tekniğine uygun olarak hazırlanan bu kitabın bütün hakları saklıdır.
İlgili kuruluştan izin almadan kitabın tümü ya da bölümleri mekanik, elektronik, fotokopi, manyetik kayıt
veya başka şekillerde çoğaltılamaz, basılamaz ve dağıtılamaz.

Copyright © by Anadolu University


All rights reserved
No part of this book may be reproduced or stored in a retrieval system, or transmitted
in any form or by any means mechanical, electronic, photocopy, magnetic tape or otherwise, without
permission in writing from the University.

UZAKTAN ÖĞRETİM TASARIM BİRİMİ

Genel Koordinatör
seafoodplus.info Müjgan Yazıcı

Genel Koordinatör Yardımcısı


Doç.Dr. İrem Erdem Aydın

Öğretim Tasarımcısı
seafoodplus.info T. Volkan Yüzer

Grafik Tasarım Yönetmenleri


Prof. Tevfik Fikret Uçar
seafoodplus.infoç. Nilgün Salur
Öğr.Gör. Cemalettin Yıldız

Kitap Yazım Basım ve Dağıtım Koordinatörü


Uzm. Nermin Özgür

Kapak Düzeni
Doç.Dr. Halit Turgay Ünalan

Grafikerler
Ayşegül Dibek
Özlem Çayırlı
Hilal Küçükdağaşan

Dizgi
Açıköğretim Fakültesi Dizgi Ekibi

Algoritmalar ve Programlama

ISBN

1. Baskı

Bu kitap ANADOLU ÜNİVERSİTESİ Basımevinde adet basılmıştır.


ESKİŞEHİR, Aralık
İçindekiler iii

İçindekiler
Önsöz vii

Algoritma Kavramı ve Programlama Temelleri 2 1. ÜNİTE


GİRİŞ 3
ALGORİTMA NEDİR? 3
Algoritmaların Temel Özellikleri 4
ALGORİTMA GÖSTERİM YÖNTEMLERİ 4
Konuşma Dili 5
Akış Şeması 5
Sözde Kod 6
ALGORİTMALARIN SINIFLANDIRILMASI 7
Özyinelemeli Algoritmalar (Simple Recursive Algorithms) 7
Geri İzlemeli Algoritmalar (Backtracking Algorithms) 8
Böl ve Yönet Algoritmaları (Divide and Conquer Algorithms) 8
Dinamik Programlama (Dynamic Programming) 9
Açgözlü Algoritmalar (Greedy Algorithms) 10
Kaba Kuvvet Algoritmaları (Brute Force Algorithms) 10
VERİ YAPILARI 10
Özet 12
Kendimizi Sınayalım 13
Kendimizi Sınayalım Yanıt Anahtarı 14
Sıra Sizde Yanıt Anahtarı 14
Yararlanılan ve Başvurulabilecek Kaynaklar 15

Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 16 2. ÜNİTE


GİRİŞ 17
DİZİLER 17
Dizilerin Tanımlanması 18
Dizilere Değer Atama 18
Çok Boyutlu Diziler 20
İki Boyutlu Diziler 20
Üç Boyutlu Diziler 21
BAĞLI LİSTELER 22
Bağlı Listeler ile Dizilerin Karşılaştırması 22
Bağlı Liste Türleri 22
Tek Yönlü Bağlı Liste 22
Çift Yönlü Bağlı Liste 23
Dairesel Bağlı Liste 23
Bağlı Listelerde Temel İşlemler 23
Düğüm Yapısını Oluşturma 23
Listeye Eleman Ekleme (Insertion) 24
Listeden Eleman Çıkarma (Deletion) 24
Listeyi Gezinme (Traversal) 24
KUYRUKLAR 26
Dizi ile Kuyruk Uygulaması 26
Bağlı Liste ile Kuyruk Uygulaması 28
YIĞINLAR 30
iv İçindekiler

Dizi ile Yığın Uygulaması 31


Bağlı Liste ile Yığın Uygulaması 32
Özet 35
Kendimizi Sınayalım 36
Kendimizi Sınayalım Yanıt Anahtarı 37
Sıra Sizde Yanıt Anahtarı 37
Yararlanılan ve Başvurulabilecek Kaynaklar 39

3. ÜNİTE Ağaçlar, Yığın Ağaçları ve Özetleme Tabloları 40


GİRİŞ 41
AĞAÇLAR 41
İkili Ağaçlar (Binary Trees) 42
İkili Ağaçlarda Gezinme Yöntemleri 43
Preorder Gezinme 43
Inorder Gezinme 44
Postorder Gezinme 44
İkili Arama Ağaçları (Binary Search Trees) 44
İkili Arama Ağacına Düğüm Ekleme 45
İkili Arama Ağacından Düğüm Çıkarma 46
AVL Ağaçları 47
AVL Ağacına Düğüm Ekleme ve Denge Korunumu 49
AVL Ağacından Düğüm Çıkarma ve Denge Korunumu 50
YIĞIN AĞAÇLARI 51
Dizi ile Yığın Ağacı Uygulaması 52
Yığın Ağacında En Küçük Elemanı Elde Etme 52
Yığın Ağacından En Küçük Elemanı Çıkarma: Aşağı Yönlendirme 52
Yığın Ağacına Eleman Ekleme: Yukarı Yönlendirme 53
ÖZETLEME (HASH) TABLOLARI 53
Çatışmalar 54
Çatışma Çözüm Yöntemleri 55
Ayrık Zincirleme (Separate Chaining) 55
Açık Adresleme (Open Addressing) 56
Özet 57
Kendimizi Sınayalım 59
Kendimizi Sınayalım Yanıt Anahtarı 61
Sıra Sizde Yanıt Anahtarı 62
Yararlanılan ve Başvurulabilecek Kaynaklar 64

4. ÜNİTE Algoritma Tasarımı 65


GİRİŞ 67
Hangi Problemler Algoritmalar ile Çözülebilir? 67
Teknolojik Olarak Algoritmalar 68
ALGORİTMA İLE PROBLEM ÇÖZME 68
ALGORİTMA TASARLAMA TEKNİKLERİ 70
Döngü-Tekrarlama Algoritmaları 70
Küçült-Fethet (Decrease&Conquer) Yöntemi ile Algoritma Tasarlama 73
Özyinelemeli Fonksiyon Algoritmaları ve Böl-Fethet (Divide & Conquer)
Yöntemi ile Algoritma Tasarımı 75
Özet 79
İçindekiler v
Kendimizi Sınayalım 80
Kendimizi Sınayalım Yanıt Anahtarı 81
Sıra Sizde Yanıt Anahtarı 81
Yararlanılan ve Başvurulabilecek Kaynaklar 82

Algoritma Analizi 84 5. ÜNİTE


GİRİŞ 85
ALGORİTMA ANALİZİ İÇİN MATEMATİKSEL ARKA PLAN 86
FONKSİYONLARIN BÜYÜMESİ 87
ALGORİTMALARIN EN KÖTÜ DURUM, EN İYİ DURUM VE
ORTALAMA DURUM VERİMLİLİKLERİ 87
ASİMPTOTİK GÖSTERİMLER 88
Büyük O Gösterimi 89
Büyük Ω Gösterimi 89
Büyük Θ Gösterimi 90
ÖZYİNELEMELİ OLMAYAN ALGORİTMALARIN ANALİZİ 91
Algoritma Analizi ile İlgili Genel Kurallar 92
Algoritma Analiz Örnekleri 93
ÖZYİNELEMELİ ALGORİTMALARIN ANALİZİ 95
Özet 98
Kendimizi Sınayalım 99
Kendimizi Sınayalım Yanıt Anahtarı
Sıra Sizde Yanıt Anahtarı
Yararlanılan ve Başvurulabilecek Kaynaklar

Arama Algoritmaları 6. ÜNİTE


GİRİŞ
ARDIŞIK ARAMA
İKİLİ ARAMA
ARAMA ALGORİTMALARININ KARŞILAŞTIRILMASI
Özet
Kendimizi Sınayalım
Kendimizi Sınayalım Yanıt Anahtarı
Sıra Sizde Yanıt Anahtarı
Yararlanılan ve Başvurulabilecek Kaynaklar

Sıralama Algoritmaları 7. ÜNİTE


GİRİŞ
BALONCUK SIRALAMASI
SEÇMELİ SIRALAMA
ARAYA SOKARAK SIRALAMA
HIZLI SIRALAMA
BİRLEŞTİREREK SIRALAMA
YIĞIN SIRALAMASI
SIRALAMA ALGORİTMALARININ ÖZELLİKLERİ
Özet
Kendimizi Sınayalım
Kendimizi Sınayalım Yanıt Anahtarı
Sıra Sizde Yanıt Anahtarı
Yararlanılan ve Başvurulabilecek Kaynaklar
vi İçindekiler

8. ÜNİTE Çizge Algoritmaları


GİRİŞ
ÇİZGELERLE İLGİLİ TEMEL KAVRAMLAR
ENİNE ARAMA ALGORİTMASI
ÖNCE DERİNLİĞİNE ARAMA ALGORİTMASI
DİJKSTRA EN KISA YOL ALGORİTMASI
Özet
Kendimizi Sınayalım
Kendimizi Sınayalım Yanıt Anahtarı
Sıra Sizde Yanıt Anahtarı
Yararlanılan ve Başvurulabilecek Kaynaklar
Önsöz vii

Önsöz
Sevgili öğrenciler,
Algoritma sözcüğü Türk Dili Kurumu tarafından “iyi tanımlanmış kuralların ve iş-
lemlerin adım adım uygulanmasıyla bir sorunun giderilmesi veya sonuca en hızlı biçimde
ulaşılması işlemi” şeklinde tanımlanmıştır. Algoritmanın bilgisayar bilimlerindeki kar-
şılığı ise “belirli bir işi yapmak veya bir problemi çözmek için adım adım tanımlanmış
işlemler kümesi” şeklinde ifade edilebilir. Bir algoritmayı belirtmek için metinsel olarak
düz bir ifade kullanabiliriz veya anlaşılabilirlik derecesi çok daha yüksek olan akış diyag-
ramlarından faydalanabiliriz. Algoritmanın bir bilgisayar tarafından gerçeklenmesi söz
konusu olduğunda ise devreye programlama ve programlama dili girer. Algoritmalar ve
Programlama kitabı size algoritma tasarımını, algoritma analizini, algoritmaların kullan-
dığı verilerin bilgisayar ortamında etkin olarak saklanmasına ve işlenmesine olanak tanı-
yan temel veri yapılarını öğretmeyi amaçlamaktadır.
Kitabımızın ilk ünitesinde algoritma kavramı, algoritmaların temel özellikleri, algo-
ritmaların gösteriminde kullanılan yöntemler ve algoritmaların sınıflandırılması konu-
larına değinilmiştir. Ayrıca, programlamada kullanılan veri yapıları konusunda ön bilgi
verilmiştir. Temel veri yapıları arasında yer alan diziler, bağlı listeler, kuyruklar ve yığınlar
ikinci ünitede; ağaçlar, yığın ağaçları ve özetleme tabloları ise üçüncü ünitede açıklanmış-
tır. Dördüncü ünitede, algoritma tasarımı ve algoritma tasarımında kullanılan teknikle-
re değinilmiştir. Kitabımızın beşinci ünitesinde algoritma analizi anlatılmış olup, gerekli
matematiksel arka plan, fonksiyonların büyümesi, algoritmaların en kötü durum, en iyi
durum ve ortalama durum verimlilikleri, asimptotik gösterimler, özyinelemeli ve özyi-
nelemelisiz algoritmaların analizi konuları anlatılmıştır. Altıncı ünitede, programlamada
sıklıkla ihtiyaç duyulan arama işlemleri için kullanılan başlıca arama algoritmaları açık-
lanmıştır. Yedinci ünitede, sıralama işlemleri için faydalanılan temel sıralama algoritmala-
rı ele alınmıştır. Kitabımızın sekizinci ve son ünitesinde ise çizge algoritmaları anlatılmış
olup, çizgelerle ilgili temel kavramlar, çizgeleri temel alan arama algoritmaları ve en kısa
yol algoritmaları hakkında bilgi verilmiştir.
Kitabımızda, algoritmaların gerçeklenmesi için C programlama dili temel alınmış ve
programlama örnekleri bu doğrultuda hazırlanmıştır. Her bir ünitede sunulan bilgiler,
açıklayıcı örneklerle desteklenmiş, konulara olan hâkimiyetinizin artmasına yönelik “Sıra
Sizde” çalışmaları sunulmuş, ünite sonunda öğrendiklerinizi sınamanıza imkân tanıyan
“Kendimizi Sınayalım” sorularına yer verilmiştir.
Algoritmalar ve Programlama kitabı yardımıyla sahip olacağınız bilgi birikimi ve
tecrübenin yalnızca eğitiminiz esnasında değil, meslek hayatınızda da fayda sağlamasını
ümit eder, hepinize başarılar dilerim.

Editör
Doç.Dr. Serkan GÜNAL
1
ALGORİTMALAR VE PROGRAMLAMA

Amaçlarımız
Bu üniteyi tamamladıktan sonra;
 Programlamanın temel unsurlarından biri olan algoritma kavramını açıklayabilecek,
 Algoritmaların gösteriminde kullanılan farklı yöntemleri listeleyebilecek,
 Çeşitli algoritma sınıflarını tanımlayabilecek,
 Verileri etkin bir şekilde organize etmeye yarayan veri yapısı kavramını
açıklayabilecek
bilgi ve beceriler kazanabileceksiniz.

Anahtar Kavramlar
• Algoritma • Özyineleme
• Akış Şeması • Dinamik Programlama
• Sözde Kod • Veri Yapısı

İçindekiler

• GİRİŞ
• ALGORİTMA NEDİR?
Algoritma Kavramı ve • ALGORİTMA GÖSTERİM YÖNTEMLERİ
Algoritmalar ve Programlama
Programlama Temelleri • ALGORİTMALARIN SINIFLANDIRILMASI
• VERİ YAPILARI
Algoritma Kavramı ve
Programlama Temelleri

GİRİŞ
Kitabımızın ilk ünitesi olan “Algoritma Kavramı ve Programlama Temelleri” ünitesinde
algoritma kavramı, algoritma gösterim yöntemleri, algoritma sınıfları ve veri yapıları yer
almaktadır.
Algoritma konusuna giriş, algoritmanın tanımı ve algoritmaların temel özellikleri “Algo-
ritma Nedir?” başlığında anlatılmıştır. Bu başlıkta günlük hayattan algoritma örnekleri ve-
rilerek, algoritma kavramının zihinlerimizde daha açık bir şekilde belirmesi hedeflenmiştir.
Algoritmaların gösteriminde kullanılan çeşitli yöntemler bulunmaktadır. “Algorit-
ma Gösterim Yöntemleri” başlığında bu yöntemlerden başlıcaları işlenmiştir. Gösterilen
her bir yöntem için açıklayıcı birer örnek verilerek, algoritmaların gösterim yöntemleri
pekiştirilmiştir.
Algoritmalar, ilgilendikleri problemler için uyguladıkları çözüm yöntemine göre sı-
nıflandırılabilir. Bir programın verimli ve etkin çalışabilmesi için programın hedefine
uygun algoritmalar kullanılmalıdır. “Algoritmaların Sınıflandırılması” başlığında başlıca
algoritma türleri gösterilmiş ve bu türlerin hangi problemler üzerinde uygulanabileceği
açıklanmıştır.
Ünitenin son bölümünde “Veri Yapıları” anlatılmıştır. Bu başlıkta, veri yapısı kavramı-
na giriş ve veri yapısının tanımı yer almaktadır. Ayrıca bu bölümde, kitabımız genelinde
işlenecek veri yapılarının listesi de verilmiştir.

ALGORİTMA NEDİR?
Algoritma, bir işin nasıl yapılacağını tarif eden adımlar kümesidir. Günlük hayatımızın
büyük kısmında, farkında olmadan da olsa algoritmalar ile karşı karşıya geliriz. Bir ye-
meğin yapılmasındaki adımları içeren yemek tarifi, yerini bilmediğimiz bir restoranı bul-
mamıza yardımcı olan yol tarifi, bir elektronik cihazın kullanım kılavuzu, algoritmaların
günlük hayatımızdaki kullanımına örnek olarak gösterilebilir.
Günlük yaşantımızda karşılaştığımız algoritma örneklerini detaylı ve açık bir şekil-
de tarif etmek mümkündür. Banka hesabımızdan nakit para temin etmemizi sağlayan
ATM’den para çekme algoritmasını adım adım inceleyelim:
• Hesabın bulunduğu bankaya ait bir ATM’ye gidilir.
• ATM önündeki bekleme kuyruğunu girilir.
• İşlem sırası gelene kadar kuyrukta beklenir.
• İşlem sırası geldiğinde, bankamatik kartı ATM’nin kart haznesine takılır.
• Bankamatik kartına ait şifre girilir ve “Giriş” tuşuna basılır.
4 Algoritmalar ve Programlama

• Para çekme menüsüne erişilir.


• Çekilecek nakit tutarı belirlenir ve “Devam” tuşuna basılır.
• ATM, bankamatik kartını kart haznesinden çıkartır.
• Bankamatik kartı ATM’den geri alınır.
• ATM, nakit parayı para haznesine doldurur.
• Nakit para ATM’den alınır.
• Para çekme işlemi tamamlanarak, işlem kuyruğundan çıkılır.
ATM’den para çekme algoritmasının yukarıda gösterilen adımlarında, bir kişinin para
çekmek için yapması gerekenler listelenmiştir. Bu örnek doğrultusunda, bir algoritmayı
oluşturan temel bileşenlerin, yapılacak işe yönelik açıklama ve işin yapılmasında izlenecek
adımlar olduğu söylenebilir. Açıklama kısmında işin tanımı yapılır ve işle ilgili detaylar
bildirilir. Adımlar kısmında ise işin başlangıcından sonuna kadar takip edilecek işlemler
belirtilir.

Çamaşır makinesi kullanarak çamaşırları yıkamak, günlük hayatta karşımıza çıkan bir al-
1 goritma örneğidir. Bu eylemi bir algoritma şeklinde ifade ediniz ve adımlarını belirtiniz.

Algoritmaların Temel Özellikleri


Algoritma kavramı, programlamadaki temel unsurlardan birisidir. Yazılım dünyasında
geliştirilen programlar, bilgisayarın yapacağı işlemleri algoritmalar aracılığıyla tarif eder.
Bilgisayar programları aracılığıyla çözülmek istenen bir problem için uygun bir algoritma
geliştirilemiyorsa, o problemin program ile çözülmesi mümkün değildir.
Algoritmalar kendi aralarında sınıflandırılabilir ve karşılaştırılabilir. Aynı işlevi gören
algoritmalar, farklı adımlara sahip olabilir. Programcılar, kendi ihtiyaçları doğrultusunda
en uygun algoritmayı tasarlamak ve kodlamak durumundadırlar.
Bir algoritmanın sahip olması gereken temel özellikler aşağıda listelenmiştir:
• Girdi ve Çıktı Bilgisi: Algoritmalarda girdi ve çıktı bilgileri olmalıdır. Girdi bilgisi
algoritmaya dışarıdan verilirken, çıktı bilgisi ise algoritma içerisinde üretilir. Bu
bilgiler, algoritma için tanımlı veri kümesine ait olmalıdır.
• Açıklık: Algoritmayı oluşturan adımlar doğru ve kesin bir şekilde tanımlanmalıdır.
• Doğruluk: Farklı girdi bilgileri ile çalışabilen algoritmalar, her girdi için doğru bir
çıktı üretmelidir.
• Sonluluk: Algoritmaların daima bir sonu olmalıdır. Girilen veri boyutundan ba-
ğımsız bir şekilde, algoritma adımları farklı bir aşamaya geçebilmeli veya son-
lanmalıdır. Algoritma adımları gerçekleştirilirken, algoritma sonsuz döngüye
girmemelidir.
• Verimlilik: Algoritmayı oluşturan adımlar, yapılan iş için kabul edilebilir bir süre
içerisinde tamamlanmalıdır.
• Genellik: Bir algoritma, aynı türdeki problemlerin hepsine uygulanabilir olmalıdır.

Bir algoritmanın verimliliği, o algoritmayı kullanan programın performansını doğrudan et-


kiler. Programların hızlı ve verimli çalışması için algoritma tasarımına özen gösterilmelidir.

ALGORİTMA GÖSTERİM YÖNTEMLERİ


Algoritmaların tanımlanmasında ve gösteriminde kullanılan farklı yöntemler mevcuttur.
Bu yöntemlerden başlıcaları konuşma dili ile gösterim, akış şeması ile gösterim ve sözde
kod (pseudocode) ile gösterimdir.
1. Ünite - Algoritma Kavramı ve Programlama Temelleri 5

Konuşma Dili
Bir algoritmanın açıklaması ve algoritmada yer alan adımlar, konuşma dili kuralları çerçe-
vesinde ifade edilebilir. Bu gösterim yönteminde, algoritma açık ve kesin bir dille tanım-
lanır. Algoritmada yer alan adımlar liste halinde yazılır.
İki pozitif tamsayının ortak bölenlerinin en büyüğünü bulmak için kullanılan Öklid
(Euclid) algoritmasının açıklaması ve adımları Şekil ’de, konuşma dili kullanılarak
gösterilmiştir.

Şekil

Açıklama: Elimizde iki adet pozitif tamsayı vardır. Bu iki sayının ortak bölenleri- Euclid
Algoritmasının
nin en büyüğü bulunacaktır. Konuşma Dili ile
Gösterimi.
Adımlar: Adım 1. Sayılardan büyük olanı A, küçük olanı B olarak isimlendir.
Adım 2. A sayısını B sayısına böl, kalanı K olarak isimlendir.
Adım 3. K sayısı 0’dan farklı ise, A sayısına B’nin değerini ata, B
sayısına da K’nın değerini ata ve Adım 2’ye geri dön. K sayısı 0 ise,
ortak bölenlerin en büyüğü B’nin değeridir.

Örnek: Elimizdeki sayılar 8 ve 12 olsun.


Adım 1. A = 12, B = 8
Adım 2. A % B = 4, K = 4
Adım 3. K = 4 olduğundan K != 0, A = 8, B = 4, Adım 2’ye dön
Adım 2. A % B = 2, K = 0
Adım 3. K == 0 olduğundan ortak bölenlerin en büyüğü B’nin değeri,
yani 4’tür.

Akış Şeması
Akış şeması, algoritmaların gösteriminde kullanılan faydalı bir yöntemdir. Bir akış şema-
sında algoritma adımlarını ifade eden kutucuklar, adımlar arası geçişleri gösteren oklar,
karar verme mekanizmaları olarak kullanılan şekiller bulunabilir.
Akış şeması, bir algoritmanın görsel halini ifade eder. Görsellik, algoritmaların daha ko-
lay anlaşılabilmesine olanak sağlar. Programcılar ve çözümleyiciler tarafından yaygın olarak
kullanılan akış şemalarını oluşturmak için birçok farklı çizim yazılımı bulunmaktadır.
İki pozitif tamsayının ortak bölenlerinin en büyüğünü bulmak için kullanılan Euclid
algoritmasının akış şeması ile gösterimi Şekil ’de verilmiştir.
6 Algoritmalar ve Programlama

Şekil
Euclid Algoritmasının
Akış Şeması ile 2 pozitif
Gösterimi. Başlangıç
tamsayı girin

A = büyük sayı
B = küçük sayı

K = A% B

HAYIR EVET
A=B B = Ortak bölenlerin
K ? 0
B=K en büyüğü

Web tarayıcıları üzerinden çevrimiçi olarak kullanılabilen (ücretsiz veya deneme amaçlı)
çizim yazılımlarından bazılarına seafoodplus.info, seafoodplus.info, seafoodplus.info bağ-
lantılarından ulaşabilirsiniz.

Sözde Kod
Sözde kod (pseudocode), bir algoritma veya program oluşturulurken kullanılan, konuş-
ma diline benzer bir yapıya sahip, programlama dillerinin detaylarından uzak bir anlatım
şeklidir.
Algoritmaların sözde kod ile gösterimi, oldukça yaygın ve etkili bir yöntemdir. Sözde
kodlarda bir programlama diline benzeyen ifadeler kullanılsa da bu ifadelerin bilgisayar
tarafından anlaşılması mümkün değildir.
Sözde kodlar, programlama mantığı ile konuşma dili cümlelerinin harmanlanma-
sından meydana gelir ve herkes tarafından rahatlıkla anlaşılabilir. Sözde kodu okuyan
bir kişi, programlama dillerinin detaylarına takılmadan, algoritmanın çalışma mantığı-
nı kavrayabilir.
İki pozitif tamsayının ortak bölenlerinin en büyüğünü bulmak için kullanılan Euclid al-
goritmasının sözde kodu Şekil ’te gösterilmiş olup, adımları aşağıdaki gibi özetlenebilir.
• 1 numaralı adımda, algoritmanın tanımı yapılmış ve iki pozitif tamsayının girdi
olarak kullanılacağı belirtilmiştir.
• 2 numaralı adımda, A sayısının B sayısına bölümünden kalan değer, K sayısına
eşitlenmiştir.
• 3 ve 6 numaralı adımlar arasında basit bir döngü kurulmuştur. Bu döngü, K sayısı
0’a eşit olana kadar devam edecektir.
• 7 numaralı adımda döngünün sonlandırıldığı belirtilmiştir.
• 8 numaralı adımda B sayısı ekrana yazdırılacaktır. Yazdırılan bu değer, algoritma-
nın girdileri için ortak bölenlerin en büyüğüdür.
• 9 numaralı adım, sözde koda ait son satırdır. Bu adımda algoritmanın tamamlan-
dığı belirtilmiştir.
1. Ünite - Algoritma Kavramı ve Programlama Temelleri 7

Şekil

1 procedure EUCLID (A, B : positive integers) Euclid Algoritmasının


Sözde Kod ile
2 K = A mod B Gösterimi.

3 while (K ! = 0)

4 A = B

5 B = K

6 K = A mod B

7 end while

8 print B

9 end procedure

ALGORİTMALARIN SINIFLANDIRILMASI
Algoritmalar, problemlerin çözümü için uyguladıkları yönteme göre sınıflandırılabilir.
Algoritmaları sınıflandırmadaki temel amaç, problemlerin çözümünde başvurulabilecek
değişik metotları ve alternatifleri tespit edebilmektir.
Ünitemizin bu bölümünde, aşağıda listelenen algoritma türleri incelenecektir:
• Özyinelemeli Algoritmalar (Simple Recursive Algorithms)
• Geri İzlemeli Algoritmalar (Backtracking Algorithms)
• Böl ve Yönet Algoritmaları (Divide and Conquer Algorithms)
• Dinamik Programlama (Dynamic Programming)
• Açgözlü Algoritmalar (Greedy Algorithms)
• Kaba Kuvvet Algoritmaları (Brute Force Algorithms)

Özyinelemeli Algoritmalar (Simple Recursive Algorithms)


Kendisini doğrudan veya dolaylı olarak çağıran algoritmalara özyinelemeli algoritma adı
verilir. Bu algoritmalarda, problemler daha küçük ve basit parçalara indirgenir. Küçük
parçalar için oluşturulan çözümlerin birleştirilmesiyle ana problemin çözümü elde edilir.
Faktöriyel hesabı, özyinelemeli bir algoritma kullanılarak çözülebilecek problemlere
güzel bir örnektir. 5 sayısının faktöriyeli bulunmak istendiğinde, 5’ten 1’e kadar olan tam-
sayılar çarpılır. Bu problemin özyinelemeli bir algoritma ile çözümünde aşağıdaki adımlar
uygulanır:
• Algoritmanın çıkış koşulu belirlenir (1! = 1).
• 2 sayısının faktöriyeli hesaplanır (2! = 1! * 2 = 2).
• 3 sayısının faktöriyeli hesaplanır (3! = 2! * 3 = 6).
• 4 sayısının faktöriyeli hesaplanır (4! = 3! * 4 = 24).
• 5 sayısının faktöriyeli hesaplanır (5! = 4! * 5 = ).
• Beklenen hesaplamaya ulaşıldığı için algoritma sonlandırılır.

Faktöriyel hesabını özyinelemeli bir algoritma aracılığıyla bulan C fonksiyonu, Örnek


’de gösterilmiştir.
8 Algoritmalar ve Programlama

ÖRNEK Faktöriyel hesabını özyinelemeli şekilde yapan fonksiyon.

int factorial(int n) {

if(n <= 1) {
return 1;
}

return n * (factorial(n-1));
}

Geri İzlemeli Algoritmalar (Backtracking Algorithms)


Geri izlemeli algoritmalar, genellikle optimizasyon problemlerinde kullanılan, prob-
lem çözümünde tüm olasılıkları deneyen algoritmalardır. Bu algoritmalarda çözüm
kademeli şekilde oluşturulur. Algoritma çözüm aşamasında ilerlerken, olası çözüm
yollarının hepsini deneyerek bir sonraki adıma geçmeye çalışır. Algoritmanın dene-
diği çözüm yolundan sonuç alınamazsa, algoritma bir önceki adımda bulunan diğer
olası çözüm yollarına geri döner.
Geri izlemeli algoritmaların kullanımı ile çözülen birçok problem vardır. Bu problem-
lerin başlıcaları aşağıda listelenmiştir:
• Sudoku: 9 x 9’luk bir tablonun her satır ve sütununda 1’den 9’a kadar sayıların ol-
ması gerekmektedir. Bazı değerlerin dolu olarak verildiği bulmaca nasıl çözülür?
• Sekiz Vezir Problemi: Sekiz vezir, bir satranç tahtasına birbirlerine hamle yapama-
yacak şekilde nasıl yerleştirilir?
• Sırt Çantası Problemi: Elimizde kapasitesi belirli bir sırt çantası, ağırlığı ve değeri
belirli nesneler vardır. Sırt çantasına hangi nesneler doldurulduğunda, çantaya ko-
nan nesnelerin toplam değeri en fazla olur?

Geri izlemeli algoritmalar ile çözülebilecek sırt çantası problemini ele aldığımızda, proble-
2 mi çözecek algoritmayı geliştirirken ne gibi önkoşulları dikkate almamız gerekir?

Böl ve Yönet Algoritmaları (Divide and Conquer Algorithms)


Böl ve yönet algoritmaları, problemlerin mümkün olan en küçük alt parçalara ayrıldığı,
her bir alt parçanın diğerlerinden bağımsız şekilde çözüldüğü algoritmalardır. Problemin
genel çözümü elde edilirken alt parçalara ait çözümler belirli bir sırayla bir araya getirilir.
Böl ve yönet algoritmaları, genellikle üç ana aşamadan meydana gelmektedir:
• Bölme (Divide): Problemin daha küçük parçalara ayrıldığı aşamadır. Problem
daha alt parçalara bölünemeyecek hale gelene kadar, özyinelemeli bir yaklaşımla
bölme işlemi gerçekleştirilir.
• Yönetme (Conquer): Problemin alt parçalarının, birbirlerinden bağımsız olarak
çözüldüğü aşamadır.
• Birleştirme (Merge): Problemin alt parçalarına ait çözümlerin, özyinelemeli bir
yaklaşımla birleştirildiği aşamadır.
Böl ve yönet algoritmalarındaki genel yaklaşım Şekil ’te görsel olarak açıklanmıştır.
1. Ünite - Algoritma Kavramı ve Programlama Temelleri 9

Şekil

a b c d e f g Problem Böl ve Yönet


Algoritmalarındaki
Genel Yaklaşım.

Böl a b c d e f g Alt Problemler

Yönet A B C D E F G Alt Çözümler

Birleştir A B C D E F G Çözüm

Dinamik Programlama (Dynamic Programming)


Dinamik programlama, karmaşık problemleri küçük parçalar halinde çözen, elde edilen Ezberleme (Memorization):
sonuçları bilgisayar hafızasında bir veri yapısında saklayan, genel çözümü elde ederken de Bir problemin alt kümelerinin
çözümlerini tekrar tekrar
veri yapılarında saklanan sonuçları kullanan bir programlama yöntemidir. hesaplamak yerine, bilgisayar
Bir problemin dinamik programlama ile çözülebilmesi için problemin alt parçalara hafızasında saklayan yöntemdir.
ayrılabilmesi ve genel çözümün bu alt parçalardan oluşturulabilmesi gerekmektedir. Di-
namik programlama yaygın olarak optimizasyon problemlerinde kullanılır.
Daha önce özyinelemeli algoritma aracılığıyla çözdüğümüz faktöriyel hesabını dina-
mik programlama ile de çözebiliriz. Faktöriyel hesabını dinamik programlama ile yapan
C programı Örnek ’de gösterilmiştir.

Faktöriyel hesabını dinamik programlama ile yapan program. ÖRNEK

#include<stdio.h>

int memory[] = {1, 1};

int factorial(int n) {
if(n <= 1) {
return 1;
}
else {
int i;

for(i=2; i<=n; i++) {


if(memory[i] == 0) {
memory[i] = i * memory[i-1];
}
}

return memory[n];
}
}

int main(void) {
int n;

for(n=1; n<10; n++) {


printf(“%d! = %d\n”, n, factorial(n));
}

getch();
return 0;
}
10 Algoritmalar ve Programlama

Açgözlü Algoritmalar (Greedy Algorithms)


Bir problem için mümkün olan en doğru çözümü hedefleyen algoritmalara açgözlü algo-
ritmalar adı verilir. Açgözlü algoritmalarda yerel olarak optimum sonuç elde edilirken,
bulunan sonuç her zaman için en iyi çözüme karşılık gelmeyebilir.
Açgözlü algoritmalar ile problem çözümündeki temel yaklaşım, problemin küçük bir
alt kümesi için çözüm oluşturmak ve bu çözümü problemin geneline yaymaktır. Algorit-
ma içerisinde yapılan bir seçim, o an için doğru olsa bile sonraki seçimlerde olumsuz etki
yapabilir.
Bir şehirden yola çıkan gezginin en fazla seyahat edeceği yolu hesaplama problemi,
açgözlü bir algoritma ile çözülebilir. Bu yöntemde, mevcut şehirden gidilebilecek en uzak
şehre gidilir. Şekil ’teki ilk haritada gezgin 7 + 12 + 9 = 28 ile en uzak mesafeyi kat eder
ve problemin en iyi çözümünü elde eder. İkinci haritada ise; gezgin yine 7 + 12 + 9 = 28
yolunu kullanır fakat en iyi çözümü elde edemez. Açgözlü algoritmanın yerel optimumda
bulamadığı 7 + 10 + 32 = 49 yolu, en fazla seyahat edilen yol olmalıdır.
Şekil
En Fazla Yol Kat
7 7
Etme Probleminin
Açgözlü Algoritma ile
Çözümü.
10 12 10 12

4 9 6 9 4 32 6 9

a. Aç gözlü algoritma ile en iyi çözüm b. Aç gözlü algoritma ile optimum


çözüm (en iyi çözüm değil)

Kaba Kuvvet Algoritmaları (Brute Force Algorithms)


Bir problemin çözümü aşamasında, kabul edilebilir bir çözüm elde edene kadar tüm ola-
sılıkları deneyen algoritmalara kaba kuvvet algoritmaları denir.
Kaba kuvvet algoritmaları, genellikle problemin tanımından yola çıkarak en basit çö-
züm yolunu uygular ve rahatlıkla kodlanır. Fakat bu algoritmalarda çok fazla işlem yapılır
ve çözüm yolu optimumdan uzaktır. Problemdeki veri hacmi büyüdükçe, kaba kuvvet
algoritması ile çözüm şansı da azalır.
Bir liste içerisinde eleman aramak, kaba kuvvet algoritmaların kullanımıyla çözülebi-
lecek problemlere bir örnektir. Listenin tüm elemanları sırayla kontrol edilerek, aranan
elemanın listede olup olmadığına bakılabilir. Listenin eleman sayısı arttıkça, kaba kuvvet
algoritmasının çalışma süresi ve yaptığı karşılaştırmalar da artacaktır.

Bir tamsayı dizisinde belirli bir tamsayıyı arayacak kaba kuvvet algoritması kodlayınız. Ge-
3 liştireceğiniz algoritma, aranan eleman dizide bulunursa 1 değerini, bulunamazsa 0 değeri-
ni çıktı olarak vermelidir.

VERİ YAPILARI
Üst düzey programlamada veri içerisinde arama yapmak, veriye hızlı bir şekilde ulaşmak,
bilgisayarın işlemcisini verimli kullanmak, aynı anda birçok isteğe cevap verebilmek gibi
gereksinimler söz konusudur. Bilgisayar programlarının karmaşıklığı ve programda işle-
nen veri büyüklüğü arttıkça, verilerin daha sistematik ve verimli yönetilmesi gerekir.
1. Ünite - Algoritma Kavramı ve Programlama Temelleri 11
Bilgisayar programlarında verilerin sistematik ve etkili bir şekilde organize edilmesi
için veri yapıları kullanılır. Bir veri yapısı, içerdiği elemanların mantıksal düzeni ve ele-
manlar üzerinde yapılabilecek işlemler ile tanımlanır.
Veri yapılarına örnek olarak, oldukça sık kullanılan bir veri yapısı çeşidi olan kuyruk
Şekil ’da gösterilmiştir. Her kuyruğun bir başı ve sonu olur. Veriler kuyruğun baş tara-
fından girerken, son tarafından çıkar. Bu özellikten dolayı kuyruk veri yapısını bir market-
teki ödeme sırasına benzetebiliriz.
Şekil

Kuyruk Sonu Kuyruk Başı Kuyruk Veri


Yapısının Baş ve
Son Taraflarının
Gösterimi.

Kitabımız genelinde ayrıntıyla incelenecek ve örneklenecek veri yapıları şunlardır:


• Diziler (Arrays)
• Bağlı Listeler (Linked Lists)
• Kuyruklar (Queues)
• Yığınlar (Stacks)
• Ağaçlar (Trees)
• Yığın Ağaçları (Heaps)
• Özetleme Tabloları (Hash Tables)
• Çizgeler (Graphs)
12 Algoritmalar ve Programlama

Özet
Programlamanın temel unsurlarından biri olan algorit- lar, kendisini doğrudan veya dolaylı olarak çağıran
1 ma kavramını açıklamak algoritmalardır. Problemler daha küçük parçalara
Bir işin nasıl yapılacağını tarif eden adımlar küme- indirgenir ve bu parçalar için oluşturulan çözümler
sine algoritma denir. Bir algoritmayı oluşturan te- birleştirilerek ana problemin çözümü elde edilir. Geri
mel bileşenler yapılacak işe yönelik açıklama ve işin İzlemeli Algoritmalar, problemin çözüm aşamasında
yapılmasında izlenecek adımlardır. Algoritmanın ilerlerken, olası çözüm yollarının hepsini deneyerek
açıklama kısmında işin tanımı yapılır ve işle ilgili bir sonraki adıma geçmeye çalışan algoritmalardır.
detaylar belirlenir. Algoritmanın adımları kısmında Denenen çözüm yolundan sonuç alınamazsa, algo-
ise işin başlangıcından sonuna kadar takip edilecek ritma bir önceki adımda bulunan diğer olası çözüm
işlemler belirtilir. yollarına döner. Böl ve Yönet Algoritmaları, problem-
Bir algoritmanın sahip olması gereken temel özellik- lerin mümkün olan en küçük alt parçalara ayrıldığı,
ler girdi ve çıktı bilgisine sahip olmak, açıklık, doğ- her bir alt parçanın diğerlerinden bağımsız şekilde
ruluk, sonluluk, verimlilik ve genelliktir. Bu özellik- çözüldüğü algoritmalardır. Dinamik Programlama,
lerden herhangi birinin eksik veya yetersiz olması, karmaşık problemleri küçük parçalar halinde çö-
algoritmanın problem çözümü üzerindeki etkinliğini zen, elde edilen sonuçları bilgisayar hafızasında bir
olumsuz etkiler. veri yapısında saklayan, genel çözümü elde ederken
de veri yapılarında saklanan sonuçları kullanan bir
Algoritmaların gösteriminde kullanılan farklı yöntem- programlama yöntemidir. Açgözlü Algoritmalar, bir
2 leri listelemek problem için mümkün olan en doğru çözümü hedef-
Algoritmaların tanımlanmasında ve gösteriminde leyen algoritmalardır. Kaba Kuvvet Algoritmaları, bir
kullanılan başlıca yöntemler konuşma dili, akış şema- problemin çözüm aşamasında, yeterli bir çözüm elde
sı ve sözde kod olarak listelenebilir. edene kadar tüm olasılıkları deneyen algoritmalardır.
Algoritmaların konuşma dili ile gösteriminde algorit-
manın açıklaması ve adımları konuşma dili kuralları Verileri etkin bir şekilde organize etmeye yarayan veri
çerçevesinde anlatılır. Algoritma net bir dille tanımla- 4 yapısı kavramını açıklamak
nır ve adımlar liste halinde yazılır. Bilgisayar programlarında verilerin sistematik ve et-
Akış şeması, algoritmaların görsel halini sunan, oku- kili bir şekilde organize edilmesi için veri yapıları kul-
nurluğunu ve anlaşılırlığını arttıran faydalı bir gös- lanılır. Bir veri yapısı, içerdiği elemanların mantıksal
terim yöntemidir. Akış şemalarında algoritma adım- düzeni ve elemanlar üzerinde yapılabilecek işlemler
larını ifade eden kutucuklar, adımlar arası geçişleri ile tanımlanır.
gösteren oklar, karar verme mekanizmaları olarak kul- Kitabımız genelinde incelenecek veri yapıları diziler
lanılan şekiller bulunabilir. (arrays), bağlı listeler (linked lists), kuyruklar (que-
Sözde kod (pseudocode), bir algoritma veya program ues), yığınlar (stacks), ağaçlar (trees), yığın ağaçları
oluşturulurken kullanılan, konuşma diline benzer bir (heaps), özetleme tabloları (hash tables) ve çizgelerdir
yapıya sahip, programlama dillerinin detaylarından (graphs).
uzak anlatımlardır. Algoritmaların sözde kod ile gös-
terimi, programlama mantığı ile konuşma dili cümle-
lerini birleştirir. Bu sayede sözde kodu inceleyen kişi,
algoritma mantığını rahatlıkla kavrar.

Çeşitli algoritma sınıflarını tanımlamak


3
Algoritmaları problemler için uyguladıkları çözüm
yöntemlerine göre sınıflandırmak mümkündür. Ünite
kapsamında Özyinelemeli Algoritmalar, Geri İzleme-
li Algoritmalar, Böl ve Yönet Algoritmaları, Dinamik
Programlama, Açgözlü Algoritmalar ve Kaba Kuvvet
Algoritmaları incelenmiştir. Özyinelemeli Algoritma-
1. Ünite - Algoritma Kavramı ve Programlama Temelleri 13

Kendimizi Sınayalım
1. Aşağıdakilerden hangisi bir algoritmadan beklenen özel-
6. int fibonacci (int n) {
liklerden biri değildir? if (n <= 0) {
a. Aynı türdeki problemlerin hepsi için geçerli olmak return 0;
b. Doğru ve kesin adımlara sahip olmak }
else if (n == 1) {
c. Sonsuz döngüye girmek return 1;
d. Dışarıdan girdi bilgisi alabilmek }
e. Farklı girdi bilgileri ile çalışabilmek else {
return fibonacci (n-1) + fibonacci (n - 2);
}
2. Bir algoritmayı oluşturan adımların doğru ve kesin bir şe- }
kilde tanımlanması, o algoritmanın hangi özelliğini temsil eder?
a. Verimlilik
Yukarıdaki kod bloğunda tanımlanan fonksiyon, hangi algo-
b. Açıklık ritma sınıfına aittir?
c. Sonluluk a. Özyinelemeli algoritmalar
d. Genellik b. Kaba kuvvet algoritmaları
e. Doğruluk c. Açgözlü algoritmalar
d. Böl ve yönet algoritmaları
3. Aynı türdeki iki problemden yalnız birini çözebilen bir algo- e. Geri izlemeli algoritmalar
ritma, hangi temel algoritma özelliğini karşılayamamaktadır?
a. Sonluluk 7. Bir çelik kasanın kilidini açmak için olası tüm şifreleri teker teker
b. Girdi ve çıktı bilgisi deneyen kişinin kullandığı yöntem, hangi algoritma sınıfına girer?
a. Kaba kuvvet algoritmaları
c. Açıklık
b. Açgözlü algoritmalar
d. Genellik
c. Geri izlemeli algoritmalar
e. Verimlilik
d. Böl ve yönet algoritmaları
e. Dinamik programlama
4. Bir algoritmayı görselleştirirken kutucukların, geçiş ok-
larının ve karar verme mekanizmalarının kullanıldığı göste- 8. Dinamik programlamada, bir problemin alt kümelerinin
rim yöntemi hangisidir? çözümlerini tekrar tekrar hesaplamak yerine bilgisayar hafı-
a. Konuşma dili zasında saklayan yönteme ne ad verilir?
b. Sözde kod a. Programlama
c. Kaynak kodu b. Sorgulama
d. Akış şeması c. Denetleme
e. Derleyici d. Hesaplama
e. Ezberleme
5. Sözde kod ile temsil edilen aşağıdaki algoritmanın amacı
9. Bilgisayar programlarında verilerin sistematik ve organi-
nedir?
ze bir şekilde saklanmasını sağlayan kavram hangisidir?
1 procedure SWAP(a, b : integers) a. Programlama dili
b. Derleyici
2 temp = a
c. Veri yapısı
3 a = b d. Ağ bağlantısı
e. Monitör
4 b = temp

5 end procedure Aşağıdakilerden hangisi bir veri yapısı türü değildir?
a. Yığın
a. İki tamsayıdan büyük olanı bulmak
b. Gösterici
b. Pozitif doğal sayılarda toplama işlemi yapmak c. Kuyruk
c. Bir tamsayı kümesinin eleman sayısını hesaplamak d. Bağlı liste
d. Bir tamsayı kümesinin en küçük elemanını bulmak e. Ağaç
e. İki tamsayının değerlerini kendi aralarında değiştirmek
14 Algoritmalar ve Programlama

Kendimizi Sınayalım Yanıt Anahtarı


1. c Yanıtınız yanlış ise “Algoritma Nedir?” konusunu ye- timizasyon probleminin çözümü için uygulanacak yöntemi
niden gözden geçiriniz. “yükte hafif, pahada ağır” sözü ile ilişkilendirebiliriz. Prob-
2. b Yanıtınız yanlış ise “Algoritma Nedir?” konusunu ye- lemin çözümü için öncelikle çantanın taşıyabileceği en fazla
niden gözden geçiriniz. ağırlık (çantanın kapasitesi) bilinmelidir. Çözüm için bilin-
3. d Yanıtınız yanlış ise “Algoritma Nedir?” konusunu ye- mesi gereken bir diğer nokta ise her bir eşyanın ağırlığı ve
niden gözden geçiriniz. maddi değeridir. Ayrıca, hiçbir eşyanın ağırlığı ve maddi de-
4. d Yanıtınız yanlış ise “Algoritma Gösterim Yöntemle- ğeri negatif olmamalıdır.
ri” konusunu yeniden gözden geçiriniz.
5. e Yanıtınız yanlış ise “Algoritma Gösterim Yöntemle- Sıra Sizde 3
ri” konusunu yeniden gözden geçiriniz. Aşağıda verilen program, bir tamsayı dizisinde belirli bir sa-
6. a Yanıtınız yanlış ise “Algoritmaların Sınıflandırılma- yıyı aramak için geliştirilmiştir. Programda yer alan “search”
sı” konusunu yeniden gözden geçiriniz. fonksiyonu, dizinin tüm elemanlarını kontrol eden kaba
7. a Yanıtınız yanlış ise “Algoritmaların Sınıflandırılma- kuvvet bir algoritma içermektedir. Dizinin elemanları sırayla
sı” konusunu yeniden gözden geçiriniz. dolaşılır, herhangi bir eleman ile aranan değer eşit olduğunda
8. e Yanıtınız yanlış ise “Algoritmaların Sınıflandırılma- algoritma 1 döndürerek sona ermekte ve sonraki elemanla-
sı” konusunu yeniden gözden geçiriniz. rın kontrol edilmesine gerek kalmamaktadır. Aranan değer,
9. c Yanıtınız yanlış ise “Veri Yapıları” konusunu yeniden dizinin hiçbir elemanının değeri ile aynı değilse, algoritma 0
gözden geçiriniz. değeri döndürerek sona ermektedir.
b Yanıtınız yanlış ise “Veri Yapıları” konusunu yeniden
gözden geçiriniz. #include<stdio.h>
#define N 10

int tamsayilar51343 = {1, 6, 9, 88, -5, 42, ,


99, 3, 5};
Sıra Sizde Yanıt Anahtarı int search(int a) {
Sıra Sizde 1 int i;
Programlamanın temel kavramlarından biri olan algoritma-
lar, günlük hayatımızda da sıklıkla karşımıza çıkmaktadır. for(i=0; i<N; i++) {
if(a == tamsayilar[i]) {
Çamaşır makinesi ile çamaşır yıkama eylemi de bir algorit- return 1;
ma yardımıyla tarif edilebilir. Çamaşır makinesi ile çamaşır }
yıkama algoritması, kirli çamaşırların yıkanmasını ve temiz- }
lenmesini tarif eder. Bu algoritmanın olası adımları aşağıda
return 0;
belirtilmiştir: }
• Çamaşır makinesinin kapağı açılır.
int main(void) {
• Yıkanacak çamaşırlar makineye doldurulur.
int n;
• Çamaşır makinesinin kapağı kapatılır.
• Çamaşıra uygun temizlik maddeleri (deterjan, yumuşatı- for(n=1; n<50; n++) {
cı, leke çıkarıcı, vs.), deterjan haznesine doldurulur. if(search(n) == 1) {
printf(“%d dizide vardir.\n”, n);
• Uygun yıkama ayarları (yıkama programı, sıcaklık, sık- }
ma, vs.) yapılır. else {
• Makinenin elektrik bağlantısının sağlandığından emin printf(“%d dizide yoktur.\n”, n);
}
olunur.
• Makinenin yıkama düğmesine basılır. }
• Yıkama işlemi bittikten sonra çamaşırlar makineden boşaltılır.
getch();
return 0;
Sıra Sizde 2 }
Sırt çantası problemindeki temel amaç, çanta içerisine dol-
durulan eşyalar ile en fazla değeri elde edebilmektir. Bu op-
1. Ünite - Algoritma Kavramı ve Programlama Temelleri 15

Yararlanılan ve Başvurulabilecek
Kaynaklar
Cormen T.H., Leiserson C.E., Rivest R.L., Stein C. () Int-
roduction to Algorithms, 3rd Edition, MIT Press.
Levitin A. () Introduction to The Design & Analysis of
Algorithms, 3rd Edition, Pearson.
Weiss M.A. () Data Structures and Algorithm Analysis
in C++, 4th Edition, Pearson.
2
ALGORİTMALAR VE PROGRAMLAMA

Amaçlarımız
Bu üniteyi tamamladıktan sonra;
 Tek boyutlu dizi tanımlamayı ve dizinin elemanlarına değer atamayı ifade ede-
bilecek,
 Çok boyutlu dizi yapılarını açıklayabilecek,
 Bağlı liste yapısını tanımlayabilecek ve bağlı liste çeşitlerini sıralayabilecek,
 Kuyruk yapısının mantığını açıklayacak ve temel kuyruk işlemlerini sıralaya-
bilecek,
 Dizilerle ve bağlı listelerle kuyruk veri yapısını oluşturabilecek,
 Yığın yapısının mantığını kavrayacak ve temel yığın işlemlerini sıralayabilecek,
 Dizilerle ve bağlı listelerle yığın veri yapısını oluşturabilecek
bilgi ve beceriler kazanabileceksiniz.

Anahtar Kavramlar
• Veri Tipi • Bağlı Liste
• Veri Yapısı • Gösterici
• Dizi • Kuyruk
• İndis • Yığın

İçindekiler
• GİRİŞ
• DİZİLER
Diziler, Bağlı Listeler,
Algoritmalar ve Programlama • BAĞLI LİSTELER
Kuyruklar ve Yığınlar
• KUYRUKLAR
• YIĞINLAR
Diziler, Bağlı Listeler,
Kuyruklar ve Yığınlar

GİRİŞ
Kitabımızın bu ünitesinde işlenen konuların ana başlıkları, programlamada temel veri
yapılarından olan diziler, bağlı listeler, kuyruklar ve yığınlardır. Tek ve çok boyutlu dizi
tanımlama, dizi elemanlarına değer atama, dizi elemanlarını gezinme ile ilgili temel bil-
giler “Diziler” başlığında anlatılmıştır. Bağlı listelerin tanımı, bağlı liste türleri ve bağlı
listelerdeki temel işlemler “Bağlı Listeler” başlığı altında verilmiştir. Kuyruk mantığı, kuy-
ruk veri yapısının temel özellikleri, bu yapıda uygulanan işlemler ve kuyruk programlama
yöntemleri “Kuyruklar” başlığında incelenmiştir. Yığın veri yapısının mantığı, bu yapıdaki
temel işlemler ve yığın programlama yöntemleri ise “Yığınlar” başlığında anlatılmıştır.
Ünitenin genelinde işlenen veri yapıları, çeşitli örnekler ve Sıra Sizde çalışmaları ile
desteklenmektedir. Örnek programların bilgisayar ortamında tekrar kodlanması, çalıştı-
rılması, değiştirilmesi sizler için öğretici ve deneyim kazandırıcı olacaktır.

DİZİLER
Dizi (array), aynı tipteki verilerin tek bir değişken altında tutulmasını sağlayan veri yapısı-
dır. Sabit bir değere sahip olan dizinin uzunluğu, dizi oluşturulurken belirlenir. Bir dizide
bulunan verilerin her biri, o dizinin bir elemanı olarak adlandırılır. Dizinin elemanlarına
erişim indis (index) adı verilen sayısal değerler aracılığıyla sağlanır. İndislerin numaralandı-
rılması 0 ile başlar, dizinin uzunluğunun 1 eksiğine kadar ardışık olarak artarak devam eder.
Örnek olarak, 8 elemanlı bir dizinin gösterimi ve indis değerleri Şekil ’de yer almaktadır.
Şekil
İlk indis Son indis Sekiz Elemanlı Bir
(birinci eleman) (sekizinci eleman) Dizinin Gösterimi ve
İndis Değerleri.

0 1 2 3 4 5 6 7 İndis değerleri

8 elemanlı bir dizi

Diziler tek veya çok boyutlu olabilir. Ünite genelinde, çalışmalar tek boyutlu diziler üzerin-
den yapılacak, çok boyutlu dizilere ünite sonunda değinilecektir.
18 Algoritmalar ve Programlama

Dizilerin Tanımlanması
C dili ile programlamada bir dizi ile işlem yapabilmek için, diğer veri tiplerindeki değiş-
kenlerde olduğu gibi, öncelikle dizinin tanımlanması gerekmektedir.
Şekil Dizilerin tanımlanmasındaki genel ifade
Dizilerin Şekil ’de gösterilmiştir. Bu ifadeye göre:
Tanımlanmasındaki a. dizi-tipi: Dizinin hangi tipteki veri-
Genel İfade. lerden oluşacağını gösterir (int, char,
double, float vb. veri tipleri olabilir).
b. dizi-adı: Tanımlanan dizinin adını ifade eder.
c. dizi-uzunluğu: Köşeli parantez içerisinde belirtilen bu değer, dizinin uzunluğunu
belirtir.

ÖRNEK int ve char tiplerinde tek boyutlu dizi tanımlamaları.

int tamsayiDizisi[10];
char karakterDizisi[20];

Örnek ’deki kod satırlarında iki farklı dizi tanımlaması yapılmıştır. İlk dizi int veri
tipinde, tamsayiDizisi adında, 10 eleman kapasiteli bir dizidir. İkinci dizi ise char veri
tipinde, karakterDizisi adında, 20 eleman kapasiteli bir dizidir.

Dizilere Değer Atama


Bir diziyi veri tipi, isim ve kapasite belirterek tanımladığımızda (Örnek ’de olduğu
gibi), bilgisayar hafızasında dizi için bir yer ayrılır; fakat dizi elemanlarına bir değer ata-
ması yapılmaz.
Dizilere değer atamak için dizi tanımlaması ile birlikte veya tanımlamadan sonra kod-
lanan çeşitli komutlar vardır. Dizinin elemanları üzerinde gezinecek döngüler aracılığıyla
dizi elemanları sıfırlanabilir, bir veri kaynağından (kullanıcı, metin dosyası, veri tabanı
vb.) alınan değerler dizinin elemanlarına atanabilir, dizi elemanlarının değerleri program-
cı tarafından kod içerisinde belirtilebilir. Bu noktada önemli olan husus, programcının
ihtiyacı doğrultusunda en doğru yöntemin uygulanmasıdır.

ÖRNEK Döngü kullanımı ile dizi elemanlarının sıfırlanması.

#include <stdio.h>

int main(void) {
int dizi[6],
int i;

for(i=0; i<6; i++) {


dizi[i] = 0;
printf(“dizi[%d] = %d\n”, i, dizi[i]);
}

getch();
return 0;
}

Örnek ’de ana fonksiyon içerisinde int veri tipinde, tamsayiDizisi adında, 6 eleman
kapasiteli bir dizi tanımlanmıştır. Daha sonrasında bir döngü aracılığıyla dizinin her ele-
manına 0 değeri atanmıştır ve bu değerler ekrana yazdırılmıştır. Bu örnekteki programın
ekran çıktısı, Program Çıktısı ’de gösterilmiştir.
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 19
Program Çıktısı Örnek ’de gösterilen programın ekran çıktısı.

dizi[0] = 0
dizi[1] = 0
dizi[2] = 0
dizi[3] = 0
dizi[4] = 0
dizi[5] = 0

Tanımlama ile birlikte dizilere değer atama. ÖRNEK

#include <stdio.h>
#define N 5

int main(void) {
int dizi151343 = {1,2,3,4,5};
int dizi251343 = {1,2};
int i;

for(i=0; i<N; i++) {


printf(“dizi1[%d] = %d\t”, i, dizi1[i]);
printf(“dizi2[%d] = %d\n”, i, dizi2[i]);
}

getch();
return 0;
}

Örnek ’te ana fonksiyon içerisinde int veri tipinde, dizi1 ve dizi2 adlarıyla, 5 eleman
kapasiteli iki dizi tanımlanmıştır. Birinci dizinin tanımlanmasında dizinin tüm elemanla-
rına değer atanmıştır. İkinci dizinin tanımlanmasında ise dizinin ilk iki elemanına değer
atanmıştır. Bu dizinin diğer elemanları otomatik olarak 0 değerini almıştır. Daha sonra
kurulan döngüde dizilerin elemanları sırayla ekrana yazdırılmıştır. Bu örnekteki progra-
mın ekran çıktısı, Program Çıktısı ’de gösterilmiştir.
Program Çıktısı Örnek ’te gösterilen programın ekran çıktısı.

dizi1[0] = 1 dizi2[0] = 1
dizi1[1] = 2 dizi2[1] = 2
dizi1[2] = 3 dizi2[2] = 0
dizi1[3] = 4 dizi2[3] = 0
dizi1[4] = 5 dizi2[4] = 0

Bir dizinin elemanlarına değer atama işlemi, dizinin tanımlanmasıyla birlikte yapılır-
ken dizinin boyutu belirtilmeyebilir. Örneğin, int dizi[] = {-3, 0, 3, 6}; şeklinde yapılan dizi
tanımlamasında, dizinin boyutu derleyici tarafından algılanır ve hatasız çalıştırılır.

Veri girişi işlemini kullanıcıya yaptırmak mümkündür. C dilinde tanımlı scanf fonksiyonu-
nu kullanarak, 5 elemanlı bir tamsayı dizisine veri girişi yapılan bir program yazınız. 1
20 Algoritmalar ve Programlama

Çok Boyutlu Diziler


Ünitenin önceki kısımlarında incelediğimiz tek boyutlu dizilerin yanı sıra, programla-
mada çok boyutlu diziler de oluşturulabilmektedir. Bu bölümde, çok boyutlu dizilerin en
yaygın kullanılanları olan, iki boyutlu ve üç boyutlu diziler işlenecektir.

İki Boyutlu Diziler


Satır ve sütunlardan oluşan tablolar şeklinde tanımlanabilen iki boyutlu diziler, çok bo-
yutlu dizilerin en yalın halidir. m adet satır, n adet sütundan oluşan iki boyutlu bir dizi,
toplam (m x n) elemana sahip olabilir. 4 satır ve 3 sütundan oluşan iki boyutlu bir dizi,
Şekil ’te gösterilmiştir.
Şekil
İki Boyutlu (4 x 3 = 4 Satır, 3
Sütun) Bir Dizinin Gösterimi.

İki boyutlu dizilerin elemanlarına değer atarken, her iki boyuttaki indisler üzerinde
dolaşılmalıdır. Bu gereksinim için iç içe geçmiş 2 adet for döngüsü kurulabilir. İki boyutlu
dizi tanımlama, bu dizinin elemanlarına değer atama ve atanan değerleri ekrana yazdırma
işlemlerini gerçekleştiren program, Örnek ’te verilmiştir.

ÖRNEK İki boyutlu dizi tanımlama ve değer atama.

#include <stdio.h>
#define M 4
#define N 3

int main(void) {

int dizi[M]51343 = {{1,2,3}, {4,5,6}, {7}, 8,9,10};

int i, j;

for(i=0; i<M; i++) {


for(j=0; j<N; j++) {
printf(“dizi[%d][%d] = %d\n”, i, j, dizi[i][j]);
}
}
getch();
return 0;
}

Örnek ’te iki boyutlu bir tamsayı dizisi tanımlanmıştır. Bu dizinin birinci boyutu-
nun uzunluğu 4, ikinci boyutunun uzunluğu ise 3 olarak atanmıştır. Dizi tanımlaması ile
birlikte dizinin elemanlarına değer ataması da yapılmıştır. Dizinin elemanlarının değerle-
ri, kurulan iç içe döngü sayesinde ekrana yazdırılmıştır. Bu programa ait ekran çıktısı ise
Program Çıktısı ’te gösterilmiştir.
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 21
Program Çıktısı Örnek ’te gösterilen programın ekran çıktısı.

dizi[0][0] = 1
dizi[0][1] = 2
dizi[0][2] = 3
dizi[1][0] = 4
dizi[1][1] = 5
dizi[1][2] = 6
dizi[2][0] = 7
dizi[2][1] = 0
dizi[2][2] = 0
dizi[3][0] = 8
dizi[3][1] = 9
dizi[3][2] = 10

Üç Boyutlu Diziler
Üç boyutlu diziler, iki boyutlu dizilerin katmanlar halinde bir araya gelmesiyle oluşur. Üç
boyutlu bir diziyi, “iki boyutlu dizilerin dizisi” olarak da tanımlamak mümkündür. Boyut
uzunlukları sırasıyla a, b, c olan üç boyutlu bir dizinin sahip olacağı toplam eleman sayısı
a)b)c kadar olur.
Üç boyutlu dizilerde dizi tanımlama ve elemanlara değer atama işlemleri, iki boyutlu
dizilerdeki işlemlere benzerlik gösterir. Üç boyutlu dizilerin elemanları gezilirken, iç içe
geçmiş 3 adet for döngüsü kurulabilir. Belirtilen işlemlerin yapıldığı bir program, Örnek
’te verilmiştir.

Üç boyutlu dizi tanımlama ve değer atama. ÖRNEK

#include <stdio.h>
int main(void) {
int d[3][2][2] = {12,11,10,9,8,7,6,5,4,3,2,1};
int i, j, k;
for(i=0; i<3; i++) {
for(j=0; j<2; j++) {
for(k=0; k<2; k++) {
printf(“%d\n”, d[i][j][k]);
}
}
}

getch();
return 0;
}

Ünite genelinde verilen örnekleri bilgisayar ortamında denemeniz, diziler hakkındaki dene-
yiminizin artmasına katkıda bulunacaktır.
22 Algoritmalar ve Programlama

BAĞLI LİSTELER
Bağlı liste (linked list), aynı türden nesnelerin doğrusal bir sırada ve birbirlerine bağlı
şekilde saklandığı veri yapısıdır. Bağlı listedeki nesnelere düğüm (node) adı verilir ve dü-
ğümler birbirlerine bir sonraki düğümü işaret eden göstericiler (next pointer) aracılığıyla
bağlanmışlardır. Ayrıca, bağlı listelerde listenin başlangıcını işaret eden bir baş gösterici
(head pointer) de bulunur.
Bağlı listeleri oluşturan düğümler genellikle iki kısımdan meydana gelir. Düğümün ilk
kısmında veri saklanırken, ikinci kısmında ise bir sonraki düğümün bilgisayar hafızasın-
daki yeri saklanır (Şekil ).
Şekil
Bağlı Listenin Liste Başı
Mantıksal Gösterimi. (Head)

next next next


Data Data Data

Bağlı Listeler ile Dizilerin Karşılaştırması


Veri yapısı olarak benzerlik gösteren dizilerin ve bağlı listelerin, birbirleriyle kıyaslandı-
ğında, çeşitli açılardan avantajları ve dezavantajları bulunmaktadır. Bağlı listelerin ve dizi-
lerin çeşitli ölçütlere göre karşılaştırması aşağıda verilmiştir:
• Veri yapısı uzunluğu: Dizilerde veri yapısının uzunluğu sabittir, gerekli durumlar-
da dizi uzunluğu arttırılamaz veya azaltılamaz. Bağlı listelerde uzunluk dinamiktir,
yeni nesneler eklenebilir, var olan nesneler silinebilir.
• Hafıza kullanımı: Bağlı listelerdeki her bir nesnenin göstericisi için, bilgisayar ha-
fızasında yer ayrılması gerekir. Dizilerde böyle bir durum söz konusu değildir.
• Veri ekleme/silme maliyeti: Dizilerde ekleme ve çıkarma işlemleri, programlama
açısından oldukça yüksek maliyetlidir. Bağlı listelerde ekleme veya çıkarma yap-
mak, dizilerdekine göre daha az maliyetli ve kolaydır.
• Verilere doğrudan erişim: Dizi elemanlarına indisler aracılığıyla doğrudan erişi-
lebilir. Bağlı listelerde ise böyle bir durum söz konusu değildir. Bağlı listenin bir
elemanına erişmek için o elemanın listede aranması ve bulunması gerekir.

Bağlı Liste Türleri


Bağlı listelerin elemanları dolaşılırken ileriye doğru gitmek, geriye doğru hareket etmek
ve listenin sonundan listenin başına erişmek mümkün olabilir. Belirtilen bu hareket kabi-
liyetleri, çeşitli türlerde bağlı listelerin ortaya çıkmasına neden olur. Bağlı listelerdeki üç
tür aşağıda listelenmiştir:
i. Tek yönlü bağlı liste (Singly linked list)
ii. Çift yönlü bağlı liste (Doubly linked list)
iii. Dairesel bağlı liste (Circular linked list)

Tek Yönlü Bağlı Liste


Tek yönlü bağlı listelerde, liste düğümleri arasındaki gezinme yalnızca ileriye doğru ger-
çekleşir. Şekil ’teki gösterim, tek yönlü bir bağlı liste örneğidir.
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 23

Çift Yönlü Bağlı Liste


Çift yönlü bağlı listelerde, liste düğümleri arasında hem ileriye hem de geriye doğru gidi-
lebilir. Çift yönlü bağlı listenin bir düğümü, bir sonraki düğümü işaret eden göstericinin
(next pointer) yanı sıra, bir önceki düğümü işaret eden göstericiyi (previous pointer) de
içerir. Çift yönlü bağlı liste için bir örnek, Şekil ’te gösterilmiştir.
Şekil
head Çift Yönlü Bağlı
Listenin Mantıksal
Gösterimi.
next next next
Data Data Data

previous previous previous

Dairesel Bağlı Liste


Bir bağlı listenin son düğümünün bir sonraki düğümü işaret eden göstericisi (next poin-
ter) listenin ilk düğümünü işaret ettiğinde liste dairesel hale gelmiş olur. Bağlı listelerin bu
çeşidine dairesel bağlı liste denilmektedir. Dairesel bağlı liste için bir örnek, Şekil ’da
gösterilmiştir.
Gerek tek yönlü gerek çift yönlü bağlı listelerin dairesel hale getirilmesi mümkündür.
Bazı kaynaklarda, dairesel bağlı listeler, kendi içlerinde tek yönlü veya çift yönlü olarak
ikiye ayrılmaktadır.
Şekil
head Dairesel Bağlı Listenin
Mantıksal Gösterimi.

next next
Data Data Data

next

Bağlı Listelerde Temel İşlemler


Bağlı listelerde listeye yeni eleman ekleme, listeden eleman çıkarma, listedeki toplam ele-
man sayısını bulma, listenin elemanlarını dolaşma, listede eleman arama, listenin ilk veya
son elemanını bulma gibi çeşitli işlemler yapılabilir. Liste üzerinde yapılabilecek işlemler,
listenin türüne göre de değişkenlik gösterir.
Bu bölümde, tek yönlü bağlı listelerdeki temel işlemler sıralanacak ve bu işlemler için
örnek kodlar gösterilecektir.

Düğüm Yapısını Oluşturma


Bağlı listenin elemanlarını temsil etmek için bir düğüm yapısı oluşturulmalıdır. Bu yapıda
düğümde saklanacak veri (data) ve bir sonraki düğümün göstericisi (next pointer) yer
alır. Tamsayı değerler saklayacak bir bağlı liste için düğüm yapısı, Örnek ’da verilmiştir.
24 Algoritmalar ve Programlama

ÖRNEK Bağlı listede düğüm yapısı.

struct Node {
int data;
struct Node* next;
};

struct Node* head = NULL;

Listeye Eleman Ekleme (Insertion)


Bağlı listelerde listenin başına, sonuna veya herhangi bir bölgesine eleman eklemek müm-
kündür. Ekleme işleminde, eklenecek düğüm için malloc fonksiyonu ile hafızada yer açı-
lır. Örnek ’de, listenin başına ekleme yapan bir fonksiyon gösterilmiştir.

ÖRNEK Bağlı listede liste başına eleman ekleme.

void insert(int a) {
struct Node* t = (struct Node*) malloc(sizeof(struct Node));

t->data = a;

t->next = head;
head = t;
}

Listeden Eleman Çıkarma (Deletion)


Bağlı listelerde listenin başından, sonundan veya herhangi bir bölgesinden eleman çı-
karılabilir. Çıkarma işleminde çıkarılacak düğüm, free fonksiyonu ile hafızadan silinir.
Çıkarma işlemi listenin ara bir bölgesinden yapılacaksa, öncelikle çıkarılacak düğüm lis-
te içerisinde bulunmalı, düğüm bulunduktan sonra çıkarma işlemi gerçekleştirilmelidir.
Bağlı listelerde çıkarma işlemini baş taraftan gerçekleştiren fonksiyon, Örnek ’de yer
almaktadır.

ÖRNEK Bağlı listede liste başından eleman çıkarma.

void delete(){
if(head != NULL) {
struct Node *t = head;

head = head->next;
free(t);
}
}

Listeyi Gezinme (Traversal)


Bağlı listenin elemanlarını gezinmek, listenin başından sonuna kadar gitmek demektir.
Gezinme işlemi, listenin son elemanına ulaşılıncaya kadar, yani bir sonraki düğümü işaret
eden göstericisi (next pointer) NULL olan eleman bulunana kadar devam eder. Listenin
elemanları gezinilirken, listede eleman arama veya elemanları ekrana yazdırma gibi iş-
lemler de yapılabilir. Örnek ’da listenin elemanlarını gezinen kod bloğu gösterilmiştir.
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 25

Bağlı listenin elemanlarının gezilmesi. ÖRNEK

void traverse(){
struct Node *t = head;

while(t != NULL){
printf(“%d “ , t->data);
t = t->next;
}
}

Tek bağlı listede temel işlemler. ÖRNEK

#include<stdio.h>

struct Node {
int data;
struct Node* next;
};

struct Node* head = NULL;

void insertToHead(int a) {
struct Node* t = (struct Node*) malloc(sizeof(struct Node));

t->data = a;
t->next = head;
head = t;
}

void deleteFromHead(){
if(head != NULL) {
struct Node *t = head;
head = head->next;
free(t);
}
}

void printList(){
struct Node *t = head;

while(t != NULL){
printf(“%d “ , t->data);
t = t->next;
}
}

int main(void) {
int i, j;

for(i=1; i<=10; i++) {


insertToHead(i);
}

for(j=1; j<=4; j++) {


deleteFromHead();
}

printList();
getch();
}
26 Algoritmalar ve Programlama

Örnek ’da temel işlemlerin uygulandığı bir tek yönlü liste programı gösterilmiştir.
Bu programda liste başına eleman eklemek için insertToHead() fonksiyonu, liste başından
eleman çıkarmak için deleteFromHead() fonksiyonu, listenin elemanlarını gezinerek ek-
rana yazdırmak için printList() fonksiyonu tanımlanmıştır.
Örneğin, ana fonksiyonunda (main) 1’den 10’a kadar çalışacak bir döngü oluşturul-
muş ve döngünün her adımında i değeri listenin başına eklenmiştir. Daha sonra, 1’den 4’e
kadar çalışacak yeni bir döngü kurulmuş ve döngünün her adımında listenin başındaki
eleman silinmiştir. Sonuç olarak, listenin son hali üzerinde gezinme yapılmış ve listede-
ki elemanlar ekrana yazdırılmıştır. Bu örnek programa ait ekran çıktısı Program Çıktısı
’te gösterilmiştir.
Program Çıktısı Örnek ’da gösterilen programın ekran çıktısı.

6 5 4 3 2 1

Ünite genelinde verilen örnekleri okumanızın yanında bilgisayar ortamında bizzat deneme-
niz, konuları özümsemenize katkı sağlayacaktır.

KUYRUKLAR
Günlük yaşantımızda kuyruğa girmek ve sıra beklemek oldukça rutin bir eylemdir. Ban-
kalarda, gişelerde, süpermarketlerde, trafikte vb. birçok alanda insanlar sıralar oluşturur,
işini bitiren kişiler kuyruktan ayrılır, yeni gelen kişiler kuyruğa dahil olur. Günlük hayat-
taki bu kuyruk mantığı, programlamada da yer almaktadır.
FIFO (First-In First-Out):
Programlamada kuyruk (queue), verilerin doğrusal sırada tutulmasını sağlayan bir
Programlamada kuyruklar FIFO veri yapısıdır. Bir kuyruğun başı (front) ve sonu (rear) bulunur. Kuyruk yapısındaki temel
kuralı ile anılır. Bu ifade, “İlk işlemler olan ekleme (enqueue) son taraftan, çıkarma (dequeue) ise baş taraftan gerçekleş-
Giren İlk Çıkar” şeklinde tercüme
edilebilir. tirilir. Dolayısıyla kuyruğa ilk giren eleman, kuyruktan ilk çıkan eleman olur (Şekil ).

Şekil
Kuyruk Veri Yapısının
Mantıksal Gösterimi.
Kuyruğa Ekleme Kuyruktan Çıkarma
(Enqueue) (Dequeue)

Kuyruğun Sonu Kuyruğun Başı


(Rear) (Front)

Kuyruk mantığının bir veri yapısı olarak programlanmasında iki temel yöntem vardır:
i. Dizilerin kullanımı ile kuyruk programlama
ii. Bağlı listelerin kullanımı ile kuyruk programlama

Dizi ile Kuyruk Uygulaması


Kuyruk veri yapısını programlarken bir diziden faydalanılabilir. Bu yöntemde, verileri
tutacak bir diziye, kuyruğun başını takip edecek bir tamsayıya, kuyruğun sonunu takip
edecek bir tamsayıya ve kuyruktaki mevcut eleman sayısını gösterecek bir tamsayıya ih-
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 27
tiyaç duyulur. Kuyruk veri yapısının tamsayı tipinde değerleri saklayacağını varsayarsak,
programda gerekli olan değişkenleri aşağıdaki gibi listeleyebiliriz:
• int queue51343: Kuyruktaki elemanları tutacak N uzunluğunda tamsayı dizisi
• int front: Kuyruğun başını gösteren indis
• int rear: Kuyruğun sonunu gösteren indis
• int count: Kuyruktaki eleman sayısı

Kuyruk veri yapısının dizi ile uygulanması. ÖRNEK

#include <stdio.h>
#define N 6

int queue51343;
int front = 0, rear = 0, count = 0;

void enqueue(int a) {
if(count == N) {
printf(“Kuyrukta yer yoktur.\n”);
}
else {
queue[rear] = a;
rear ++;
if(rear == N) rear = 0;
count ++;
printf(“%d kuyruga eklendi.\n”, a);
}
}

void dequeue() {
if(count == 0) {
printf(“Kuyrukta eleman yoktur.\n”);
}
else {
int a = queue[front];
front ++;
if(front == N) front = 0;
count --;
printf(“%d kuyruktan cikarildi.\n”, a);
}
}

Örnek ’de, dizi ile kuyruk uygulamasının nasıl yapılabileceği gösterilmiştir. Kuy-
rukta tamsayı verileri saklayacak diziye queue adı verilmiş, dizinin boyutu ise 6 olarak
tanımlanmıştır. Kuyruk yapısı için gerekli diğer değişkenler olan front, rear ve count tam-
sayıları programın başında 0 olarak atanmıştır. Kuyruğa ekleme yapmak için enqueue()
fonksiyonu, kuyruktan çıkarma yapmak için dequeue() fonksiyonu tanımlanmıştır.
Ekleme işleminde öncelikle kuyruğun doluluğu (dizinin uzunluğu olan N ile count
değişkenini karşılaştırarak) kontrol edilir ve kuyrukta yer varsa işleme devam edilir. Kuy-
ruğa eklenecek a sayısı, queue dizisinin rear ile belirtilen indisine (kuyruğun sonunu) kay-
dedilir, rear değeri ve dizinin eleman sayısı 1 arttırılır.
Çıkarma işleminde öncelikle kuyruktaki eleman sayısı (count değişkeni ile 0 değerini
karşılaştırarak) kontrol edilir ve kuyrukta herhangi bir eleman varsa işleme devam edilir.
Kuyruktan çıkarılacak değer, queue dizisinin front ile belirtilen indisinde yer almaktadır.
Çıkarma işlemiyle front değeri 1 arttırılırken, dizinin eleman sayısı 1 azaltılır. Örnekte,
kuyruktan çıkarılan değer a sayısına atanarak ekrana yazdırılmıştır, fakat ekrana yazdırma
dışında, bu değer kullanılarak farklı işlemler de gerçekleştirilebilir.
28 Algoritmalar ve Programlama

Ekleme ve çıkarma işlemlerinde önemli bir ayrıntı, queue dizisinde dairesel bir yapı
kurulmasıdır. Eklemede rear değişkeni, çıkarmada ise front değişkeni dizinin eleman sayı-
sına eşit olursa, ilgili değişken 0 değerine atanır. Böylelikle dizide dairesel bir yapı kurulur
ve programın dizi indislerinden bağımsız, kesintisiz olarak çalışması sağlanır.

Örnek ’i temel alarak, bir kuyruk uygulaması geliştirin. Yazacağınız programda kuyru-
2 ğa sırasıyla 5, 12, 9, 8, 0, 1, 7 sayılarını ekleyin, kuyruktan çıkarma işlemini 2 defa uygulayın,
kuyruğa tekrar 5 sayısını ekleyin.

Bağlı Liste ile Kuyruk Uygulaması


Kuyruk yapısını programlamak için bir bağlı listeden de faydalanılabilir. Bu yöntemde
bağlı listenin elemanlarını oluşturacak bir veri yapısına ve kuyruğun başını ve sonunu
takip edecek göstericilere ihtiyaç duyulur.
Şekil
Kuyruk Veri front rear
Yapısında Bağlı Liste
Kullanımı.
9 2 6 Kuyruğun
varsayılan ilk hali

front enqueue(8) rear

Kuyruğa 8
9 2 6 8
eklenmesinden
sonraki durum

front dequeue() rear

Kuyruktan
2 6 8
çıkarmadan
sonraki durum

Kuyruk veri yapısının bağlı liste ile gösterimi, Şekil ’de belirtilmiştir. Kuyruğun ilk
halinde 9, 2 ve 6 sayılarını içeren elemanlar bulunmaktadır. 9 sayısını içeren eleman kuy-
ruğun başında, 6 sayısını içeren eleman ise kuyruğun sonundadır. Tanımlanan bu kuy-
ruğa, enqueue işlemi ile 8 sayısını içeren bir eleman eklenmiştir ve kuyruğun sonu, bu
elemanı gösterecek şekilde güncellenmiştir. Daha sonraki aşamada, dequeue ile kuyruğun
başındaki eleman kuyruktan çıkarılmıştır ve kuyruğun başı, 2 sayısını içeren elemanı gös-
terecek şekilde güncellenmiştir.
Bağlı liste kullanımı ile kuyruk uygulamasında tamsayı tipinde değerlerin saklanacağı-
nı varsayarsak, ihtiyaç duyduğumuz değişkenleri aşağıdaki gibi listeleyebiliriz:
• struct Node: Bağlı listeyi oluşturacak elemanlar için veri yapısı
• struct Node) front: Kuyruğun başını ifade eden Node gösterici
• struct Node) rear: Kuyruğun sonunu ifade eden Node gösterici
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 29

Kuyruk veri yapısının bağlı liste ile uygulanması. ÖRNEK

#include<stdio.h>
#include<stdlib.h>

struct Node {
int data;
struct Node* next;
};

struct Node* front = NULL;


struct Node* rear = NULL;

void enqueue(int a) {
struct Node* t = (struct Node*) malloc(sizeof(struct Node));

t->data = a;
t->next = NULL;

if(front == NULL && rear == NULL){


front = rear = t;
}
else {
rear->next = t;
rear = t;
}

printf(“%d kuyruga eklendi\n”, a);


}

void dequeue() {
if(front == NULL) {
printf(“Kuyrukta eleman yoktur\n”);
}
else {
struct Node* t = front;

if(front == rear) {
front = rear = NULL;
}
else {
front = front->next;
}
printf(“%d kuyruktan cikarildi\n”, t->data);
free(t);
}
}

Örnek ’de bağlı liste ile kuyruk uygulamasının nasıl yapılabileceği gösterilmiştir.
Kuyrukta tamsayı değerler saklayacak bağlı liste için Node adında bir yapı oluşturulmuş-
tur. Bu yapı, data adında bir tamsayı değişkenden ve listenin bir sonraki elemanını işaret
eden, next olarak adlandırılmış Node göstericisinden meydana gelmektedir.
Program içerisinde front ve rear adlarıyla tanımlanmış Node yapıları, bağlı listenin
başını ve sonunu işaret etmektedir. Bu değerler tanımlanırken NULL olarak atanmışlar-
dır. Kuyruğa ekleme yapmak için enqueue() fonksiyonu, kuyruktan çıkarma yapmak için
dequeue() fonksiyonu tanımlanmıştır.
30 Algoritmalar ve Programlama

Ekleme işleminde malloc fonksiyonu ile yeni eleman (t adı verilen Node gösterici) için
hafızada yer açılır. Eklenecek a tamsayısı, t’nin data değişkenine atanır ve t’nin next göste-
ricisi NULL olarak belirlenir. Bağlı liste boş ise (front ve rear göstericilerinin her ikisinin
de NULL olması durumu), front ve rear göstericileri t’ye eşitlenir. Bağlı liste boş değilse,
kuyruğun sonu t olacak şekilde tanımlama yapılır.
Çıkarma işleminde öncelikle kuyruğun başı (front göstericisinin NULL olması) kont-
rol edilir ve kuyruğun başında bir eleman varsa işleme devam edilir. Kuyruğun başını
işaret eden bir gösterici tanımlanır. Bağlı listede tek bir eleman varsa (front ve rear göste-
ricilerinin eşit olması), front ve rear göstericileri NULL değerine atanır. Bağlı listede bir-
den fazla eleman varsa, kuyruğun başı, kuyruğun en baştan ikinci elemanı olacak şekilde
tanımlama yapılır. free fonksiyonu ile kuyruğun başındaki eleman, hafızadan kaldırılır.

Örnek ’de verilen kodu kullanarak, kuyruğa ekleme ve çıkarma işlemleri yapan, kuyruk-
3 taki elemanları sırayla ekrana yazan bir program geliştirin. Geliştirdiğiniz programda kuy-
ruğa sırasıyla 5, 12, 9, 1, 7 sayılarını ekleyin, kuyruktan çıkarma işlemini 2 defa uygulayın,
kuyruğa tekrar 5 sayısını ekleyin. Kuyruğun son halini ekrana yazın.

Verilen örnekleri bilgisayar ortamında denemeniz, kuyruklar hakkındaki deneyiminizin


artmasına katkıda bulunacaktır.

YIĞINLAR
Yaşantımızdaki çeşitli aktivitelerde nesnelerin üst üste dizilmesi gerekir. Üniversite ye-
mekhanesindeki tepsiler, restoran mutfağındaki tabaklar, elbise dolabı rafındaki kıyafet-
ler, nesnelerin günlük yaşamda üst üste dizilmesi için gösterilebilecek basit örneklerdir.
Bir üniversite yemekhanesindeki tepsilerden almak istediğimizde, temiz tepsilerin içeri-
sinden en üstte olanı alırız. Temiz tepsiler biriktirilirken, yeni gelen tepsiler var olanların
üstüne eklenir. Nesnelerin üst üste dizilimi, günlük hayatta olduğu gibi programlamada da
var olan bir gereksinimdir. Bu ihtiyaç, yığın (stack) adı verilen veri yapıları ile karşılanır.
LIFO (Last-In First-Out): Yığın, verilerin doğrusal bir şekilde tutulduğu, ekleme ve çıkarma işlemlerinin en üst
Programlamada yığınlar LIFO noktadan yapıldığı bir veri yapısıdır. Eklenen veri, yığının en üst noktasında saklanırken;
kuralı ile anılır. Bu ifade, “Son
Giren İlk Çıkar” şeklinde tercüme çıkarılan veri de yığının en üst noktasından alınır. Yığının en üst noktasının takibi, yığının
edilebilir. tepe noktası (top) aracılığıyla sağlanır (Şekil ).
Şekil
Yığın Veri Yapısının
Mantıksal Gösterimi.

Yığının tepe noktası


(top)

Yığın (stack)

Programlamada, yığınlar üzerinde yapılan temel işlemler eleman ekleme (push), ele-
man çıkarma (pop) ve en üstteki elemanı elde etmedir (peek). Pop işleminde en üstte-
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 31
ki eleman yığından çıkarılırken, peek işleminde yalnızca bu elemanın değeri elde edilir,
eleman yığından çıkarılmaz. Bu işlemlerin yanı sıra yığının doluluk kontrolü (isFull) ve
yığının boşluk kontrolü (isEmpty) gibi yardımcı fonksiyonlar da kullanılabilir.
Yığın mantığının bir veri yapısı olarak programlanmasında iki temel yöntem vardır:
i. Dizilerin kullanımı ile yığın programlama
ii. Bağlı listelerin kullanımı ile yığın programlama

Dizi ile Yığın Uygulaması


Yığın veri yapısını programlamada bir diziden faydalanılabilir. Bu yöntemde verileri tu-
tacak bir diziye ve yığının tepe noktasını takip edecek bir tamsayıya ihtiyaç vardır. Yığın
veri yapısının tamsayı tipinde değerleri saklayacağını varsayarsak, programda gerekli olan
değişkenleri aşağıdaki gibi listeleyebiliriz:
• int stack51343: Yığındaki elemanları tutacak N uzunluğunda tamsayı dizisi
• int top: Yığının tepe noktasını gösteren indis

Yığın veri yapısının dizi ile uygulanması. ÖRNEK

#include<stdio.h>
#define N 10

int stack51343;
int top = -1;

void push(int a) {
if(top == N-1) {
printf(“Yiginda yer yoktur.\n”);
}
else {
stack[++ top] = a;
printf(“%d yigina eklendi.\n”, a);
}
}

int pop() {
if(top < 0) {
printf(“Yiginda eleman yoktur.\n”);
return -1;
}
else {
int a = stack[top --];
printf(“%d yigindan cikarildi.\n”, a);
return a;
}
}

int peek() {
if(top < 0) {
printf(“Yiginda eleman yoktur.\n”);
return -1;
}
else {
printf(“%d yiginin tepe noktasindadir.\n”, stack[top]);
return stack[top];
}
}

Örnek ’te dizi ile yığın uygulamasının nasıl yapılabileceği gösterilmiştir. Yığında
tamsayı verileri saklayacak diziye stack adı verilmiş, dizinin boyutu 10 olarak tanımlan-
32 Algoritmalar ve Programlama

mıştır. Yığın yapısı için gerekli diğer bir değişken olan top, program başında -1 değeri
almıştır. Yığına ekleme yapmak için push() fonksiyonu, yığından çıkarma yapmak için
pop() fonksiyonu, yığının en tepesindeki elemanı elde etmek için ise peek() fonksiyonu
tanımlanmıştır.
Ekleme işleminde öncelikle yığının doluluğu (dizinin son elemanının indisi olan N-1
ile top değişkenini karşılaştırarak) kontrol edilir ve yığında yer varsa işleme devam edilir.
Yığına ekleme işlemi yapılabilecek ise top değişkeninin değeri 1 arttırılır, a tamsayısı dizi-
nin top değerindeki indisine kaydedilir.
Çıkarma işleminde ve en üstteki elemanı elde ederken benzer işlemler yapılır. Önce-
likle yığında eleman olup olmadığı kontrol edilir (top değişkeni ile 0 değerini karşılaştıra-
rak). Yığında eleman varsa, a değişkenine dizinin top indisindeki değer atanır. Çıkarmada,
top değişkeninin değeri 1 azaltılırken, en üstteki elemanı elde edilirken top değişkeninin
değeri değiştirilmez. Fonksiyon, a değişkenini döndürür.

Bağlı Liste ile Yığın Uygulaması


Yığın yapısını programlamak için bir bağlı listeden de faydalanılabilir. Bu yöntemde bağlı
listenin elemanlarını oluşturacak bir veri yapısına ve yığının tepe noktasını takip edecek
bir göstericiye ihtiyaç duyulur.
Şekil
Yığın Veri Yapısında top
Bağlı Liste Kullanımı.

9 2 6 Yığının
varsayılan
ilk hali

top push(8)

8 9 2 6 Yığına 8
eklenmesinden
sonraki durum

top pop()

Yığından
9 2 6
çıkarmadan
sonraki durum

peek()

9 2 6 Yığının en üst
elemanının
getirmeden
sonraki durum

Şekil ’da yığın veri yapısının bağlı liste ile gösterimine yer verilmiştir. Yığının ilk
halinde 9, 2 ve 6 sayılarını içeren elemanlar bulunmaktadır. Yığının tepe noktası, 9 sa-
yısını içeren elemanı göstermektedir. Tanımlanan bu yığına, öncelikle push işlemi ile 8
sayısını içeren bir eleman eklenmiştir ve yığının tepe noktası, bu yeni eklenen 8 sayısını
içeren elemanı gösterecek şekilde güncellenmiştir. Daha sonraki aşamada, pop işlemi ile
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 33
yığının en üstündeki eleman yığından çıkarılmıştır ve yığının başı, 9 sayısını içeren ele-
manı gösterecek şekilde güncellenmiştir. Son olarak, peek işlemi ile yığının en üstündeki
elemanın değeri, yani 9 sayısı elde edilmiştir. Bu işlem sonucunda yığının tepe noktasında
bir değişiklik olmamıştır.

Yığın veri yapısının bağlı liste ile uygulanması. ÖRNEK

#include<stdio.h>

struct Node {
int data;
struct Node* next;
};

struct Node* top = NULL;

void push(int a) {
struct Node* t = (struct Node*) malloc(sizeof(struct Node));

t->data = a;

if(top == NULL){
top = t;
top->next = NULL;
}
else {
t->next = top;
top = t;
}
printf(“%d yigina eklendi\n”, a);
}

int pop() {
if(top == NULL) {
printf(“Yiginda eleman yoktur\n”);
return -1;
}
else {
struct Node* t = top;
int a = t->data;

top = top->next;

printf(“%d yigindan cikarildi\n”, a);


free(t);

return a;
}
}

int peek() {
if(top == NULL) {
printf(“Yiginda eleman yoktur\n”);
return -1;
}
else {
printf(“%d yiginin tepe noktasindadir\n”, top->data);
return top->data;
}
}
34 Algoritmalar ve Programlama

Örnek ’te bağlı liste ile yığın uygulamasının nasıl yapılabileceği gösterilmiştir. Yı-
ğında tamsayı değerler saklayacak bağlı liste için Node adında bir yapı oluşturulmuştur.
Bu yapı, data adında bir tamsayı değişkenden ve listenin bir sonraki elemanını işaret eden,
next olarak adlandırılmış Node göstericisinden meydana gelmektedir.
Program içerisinde top adıyla tanımlanmış Node yapısı, bağlı listenin tepe noktasını
işaret etmektedir. Bu değerler tanımlanırken NULL olarak atanmışlardır. Yığına ekleme
yapmak için push() fonksiyonu, yığından çıkarma yapmak için pop() fonksiyonu, yığının
en üstündeki elemanın değerini elde etmek için peek() fonksiyonu tanımlanmıştır.
Ekleme işleminde malloc fonksiyonu ile yeni eleman (t adı verilen Node gösterici) için
hafızada yer açılır ve eklenecek a tamsayısı, t’nin data değişkenine atanır. Bağlı liste boş ise
(top göstericinin NULL olması), top göstericisi t’ye eşitlenir. Bağlı liste boş değilse, yığının
en üzerinde t olacak şekilde tanımlama yapılır.
Çıkarma işleminde öncelikle yığının tepe noktası kontrol edilir (top göstericinin NULL
olması) ve yığında herhangi bir eleman varsa işleme devam edilir. Yığının tepe noktasını
işaret eden, t adında bir gösterici tanımlanır ve buradaki elemanın değeri a değişkenine
atanır. Yığının tepe noktası, t göstericisinin next ile tanımlanmış elemanına kaydırılır. t adı
ile tanımlanmış eleman free fonksiyonu ile hafızadan silinir. Çıkarma fonksiyonu sonuç
olarak yığından çıkarılan elemanın değeri olan a sayısını döndürür.
En üstteki elemanı elde ederken, yığının tepe noktası kontrol edilir. Yığında herhangi
bir eleman varsa, yığının en üstünü işaret eden top göstericinin data değeri sonuç olarak
döndürülür.

Verilen örnekleri bilgisayar ortamında bizzat denemeniz, yığınlar hakkındaki deneyimini-


zin artmasına katkıda bulunacaktır.
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 35

Özet
Tek boyutlu dizi tanımlamayı ve dizinin elemanlarına Kuyruk yapısının mantığını açıklamak ve temel kuyruk
1 değer atamayı ifade edebilecek 4 işlemlerini sıralamak
Dizi, aynı türden verilerin tek bir isim altında tutul- Kuyruk (queue), verilerin doğrusal bir sırada saklan-
masını sağlayan bir veri yapısıdır. Bir dizinin uzun- dığı, kuyruk başının (front) ve sonunun (rear) takip
luğu, dizinin tanımlanması esnasında belirlenir ve bu edildiği bir veri yapısıdır.
uzunluk sabit kalır. Dizi tanımlamadaki genel ifade, Kuyruğa eleman ekleme (enqueue) ve kuyruktan
dizide saklanacak veri tipinden, dizinin adından ve eleman çıkarma (dequeue), kuyruk veri yapısındaki
dizinin uzunluğundan meydana gelir. temel işlemlerdir. Eklenen elemanlar kuyruk sonuna
Dizinin elemanlarına erişim, indis adı verilen sayılar kaydedilirken, çıkarılan elemanlar ise kuyruk başın-
aracılığıyla gerçekleşir. Dizilerin indis değeri 0’dan dan alınır. Dolayısıyla kuyruğa giren ilk eleman, kuy-
başlar, dizinin uzunluğunun 1 eksiğine kadar artarak ruktan da ilk çıkar. Bu kural, programlamada FIFO
devam eder. Dizinin elemanlarına değer atama işlemi, (First-In First-Out) olarak anılır.
dizi tanımlaması ile birlikte veya dizi elemanlarını in-
disler aracılığıyla gezinerek yapılabilir. Dizilerle ve bağlı listelerle kuyruk veri yapısını
5 oluşturmak
Çok boyutlu dizi yapılarını açıklamak Kuyruk mantığını programlamak için bir diziden
2
Diziler tek boyutlu olabildikleri gibi, birden fazla bo- veya bir bağlı listeden faydalanılabilir. Dizi kullanımı
yuta da sahip olabilirler. Programlamada en sık kul- ile kuyruk programlarken, kuyruğun mevcut eleman
lanılan çok boyutlu diziler, iki ve üç boyutludur. İki sayısını takip etmek ve diziyi dairesel bir yapıya oturt-
boyutlu bir dizi, satır ve sütunlardan oluşan bir tablo mak gerekir. Bağlı liste kullanımı ile kuyruk program-
şeklinde düşünülebilir. Üç boyutlu bir dizi ise iki bo- lamada ise kuyruğun eleman sayısının takibi gerekli
yutlu dizilerin dizisi olarak tanımlanabilir. değildir, ancak yazılan kod daha karmaşıktır.
Çok boyutlu dizilerde, dizi elemanlarını gezinmek
için dizinin tüm boyutlarını dolaşmak gerekir. Bu ge- Yığın yapısının mantığını kavramak ve temel yığın
reksinim için iç içe geçmiş for döngüleri kullanılabilir. 6 işlemlerini sıralamak
Yığın (stack), eleman ekleme ve çıkarma işlemlerinin
Bağlı liste yapısını tanımlamak ve bağlı liste çeşitlerini en üst noktadan yapıldığı veri yapısıdır. Yığın veri ya-
3 sıralamak pısında yığının tepe noktası (top) takip edilir.
Bağlı liste (linked list), aynı türden nesnelerin doğru- Yığın için tanımlı temel işlemler eleman ekleme
sal bir sırada ve birbirlerine bağlı şekilde saklandığı (push), eleman çıkarma (pop) ve en üstteki elemanın
veri yapısıdır. Bağlı listedeki nesnelere düğüm (node) değerini getirmedir (peek). Yığında ekleme ve çıkar-
denir. Genellikle iki kısımdan oluşan düğümler, bir- ma işlemleri her zaman yığının en üstünden gerçek-
birlerine göstericiler aracılığıyla bağlanır. Ayrıca, leşir. Dolayısıyla yığına son giren eleman, yığından
bağlı listelerde listenin başlangıcını işaret eden bir baş da ilk çıkar. Bu kural, programlamada LIFO (Last-In
gösterici (head pointer) de bulunur. First Out) olarak adlandırılır.
Bağlı listeler, liste içerisindeki hareket kabiliyetine
göre 3 temel kategoriye ayrılır. Sadece ileri yönde ha- Dizilerle ve bağlı listelerle yığın veri yapısını oluşturmak
7
reket edilebilen listeler tek yönlü, hem ileri hem de Yığınların programlamasında bir dizi veya bir bağlı
geri hareket edilebilen listeler çift yönlü, liste sonun- liste kullanmak mümkündür. Dizi ile yığın program-
dan liste başına geçiş yapılabilen listeler ise dairesel lamada yığının üst noktası bir indis değeri ile takip
olarak tanımlanır. edilirken, bağlı liste ile yığın programlamada yığının
üst noktasını işaret eden bir gösterici kullanılır.
36 Algoritmalar ve Programlama

Kendimizi Sınayalım
1. Aşağıdaki seçeneklerden hangisi 10 elemanlı bir dizinin 6. Aşağıdaki veri yapılarından hangisi, “İlk giren, ilk çıkar.”
ilk ve son indislerine ait numaraları göstermektedir? şeklinde tercüme edilen FIFO (First-In First-Out) kuralı ile
a. 0 ve 1 birlikte anılmaktadır?
b. 0 ve 9 a. Dizi
c. 0 ve 10 b. Tek yönlü bağlı liste
d. 1 ve 9 c. Çift yönlü bağlı liste
e. 1 ve 10 d. Yığın
e Kuyruk
2. Aşağıdaki dizi tanımlamalarından hangisi derleyici tara-
7. Dizgi tipinde verileri saklayacak şekilde tanımlanmış
fından derlendiğinde bir hata meydana gelir?
bir kuyruğa “Java”, “Ruby”, “Perl”, “Python”, “JavaScript”, ve
a. double dizi[3];
“C++” dizgileri yazılış sırasıyla ekleniyor. Sonrasında deque-
b. double dizi[3] = {}; ue işlemi ile kuyruktan 2 eleman çıkarılıyor. Oluşan son du-
c. int dizi[] = {1, 2, 3}; rumda, kuyruğun başında hangi eleman yer alır?
d. int dizi[4] = {1, 2, 3}; a. C++
e. int dizi[4] = {0, 1, 2, 3, 4}; b. Perl
c. Ruby
3. Aşağıdakilerden hangisi diziler ve bağlı listelerin farklılık d. JavaScript
gösterdiği durumlardan değildir? e. Python
a. Veri ekleme maliyeti
b. Veri çıkarma maliyeti 8. Aşağıdaki veri yapılarından hangisi “Son giren, ilk çıkar.”
c. Hafıza kullanımı şeklinde tercüme edilen LIFO (Last-In First-Out) kuralı ile
d. Değişken isimlendirme birlikte anılır?
e. Verilere doğrudan erişim a. Yığın
b. Kuyruk
4. Bir bağlı listede, listenin en sonundan en başına geçe- c. Dizi
bilme imkanı varsa, o bağlı listenin hangi alt kategoriye ait d. Çift yönlü bağlı liste
olduğu söylenir? e. Dairesel bağlı liste
a. Tek yönlü bağlı liste
9.
b. Çift yönlü bağlı liste struct Node {
c. Dairesel bağlı liste int data;
struct Node* next;
d. Serbest bağlı liste };
e. Dizi yapısında bağlı liste struct Node* top = NULL;
int peek() {
5. if(top == NULL) {
#include<stdio.h>
return -1;
struct Node { }
int data; else {
struct Node* next; return top->data;
}; }
}
struct Node* head = NULL;
void traverse(){ Yığın veri yapısı için hazırlanmış yukarıdaki koda göre, peek
struct Node *t = head; fonksiyonun işlevi nedir?
while(t != NULL){ a. Yığına yeni bir eleman eklemek
printf(“%d “ , t->data); b. Yığının en üzerindeki elemanı silmek
t = t->next; c. Yığında bulunan elemanları ekrana yazdırmak
}
} d. Yığının tepe noktasını bir aşağı kaydırmak
e. Yığının tepe noktasındaki elemanın değerini döndürmek
Tek yönlü bir bağlı liste için hazırlanmış yukarıdaki koda
Tamsayı tipinde verileri saklayacak şekilde tanımlanmış
göre, traverse fonksiyonun görevi nedir?
bir yığına 4, 5, 2, 1, 3 sayıları yazılış sırasıyla eklendiğinde,
a. Listenin elemanlarını dolaşıp, ekrana yazmak
yığının tepe noktasında hangi eleman yer alır?
b. Listeye yeni eleman eklemek a. 1
c. Listenin ilk elemanını silmek b. 2
d. Listenin son elemanını silmek c. 3
e. head göstericisini sıfırlamak d. 4
e. 5
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 37

Kendimizi Sınayalım Yanıt Anahtarı Sıra Sizde Yanıt Anahtarı


1. b Yanıtınız yanlış ise “Diziler” konusunu yeniden göz- Sıra Sizde 1
den geçiriniz. Aşağıda gösterilen program, 5 elemanlı bir tamsayı dizisine
2. e Yanıtınız yanlış ise “Diziler” konusunu yeniden göz- kullanıcının veri girişi yapmasını sağlar. Kullanıcı tarafından
den geçiriniz. girilen değerler, program çıktısı olarak ekrana yazdırılır.
3. d Yanıtınız yanlış ise “Bağlı Listeler” konusunu yeni-
den gözden geçiriniz. #include <stdio.h>
4. c Yanıtınız yanlış ise “Bağlı Listeler” konusunu yeni- #define N 5

den gözden geçiriniz. void yazdir(int a[]) {


int i;
5. a Yanıtınız yanlış ise “Bağlı Listeler” konusunu yeni-
den gözden geçiriniz. for(i=0; i<N; i++) {
printf(“%d. sayi = %d\n”, i+1, a[i]);
6. e Yanıtınız yanlış ise “Kuyruklar” konusunu yeniden }
gözden geçiriniz. }
7. b Yanıtınız yanlış ise “Kuyruklar” konusunu yeniden int main(void) {
gözden geçiriniz. printf(“Lutfen %d adet tamsayi giriniz:\n”, N);
8. a Yanıtınız yanlış ise “Yığınlar” konusunu yeniden int dizi51343;
gözden geçiriniz. int i;
9. e Yanıtınız yanlış ise “Yığınlar” konusunu yeniden for(i=0; i<N; i++) {
gözden geçiriniz. scanf(“%d”, &dizi[i]);
}
c Yanıtınız yanlış ise “Yığınlar” konusunu yeniden
yazdir(dizi);
gözden geçiriniz. getch();

return 0;
}

Sıra Sizde 2
Bu alıştırmada sizden bekleneni karşılamak için, aşağıdaki
ana fonksiyonu yazmanız ve örnekte belirtilen kod ile birlikte
çalıştırmanız gerekir.

int main(void) {

enqueue(5);
enqueue(12);
enqueue(9);
enqueue(8);
enqueue(0);
enqueue(1);
enqueue(7);

dequeue();
dequeue();

enqueue(5);

getchar();
return 0;
}
38 Algoritmalar ve Programlama

Sıra Sizde 3
Bu alıştırmada sizden beklenen, Örnek ’de verilen prog-
rama uygun bir ana fonksiyon ve kuyruk içeriğini ekrana
yazdıran bir fonksiyon yazmaktır. Aşağıda verilen program,
sizden istenilenleri karşılamaktadır.

#include<stdio.h>
#include<stdlib.h>
struct Node {
int data;
struct Node* next;
};
struct Node* front = NULL;
struct Node* rear = NULL;
void enqueue(int a) {
struct Node* t = (struct Node*) malloc(sizeof(struct Node));
t->data = a;
t->next = NULL;
if(front == NULL && rear == NULL){
front = rear = t;
}
else {
rear->next = t;
rear = t;
}
printf(“%d kuyruga eklendi.\n”, a);
}
void dequeue() {
if(front == NULL) {
printf(“Kuyrukta eleman yoktur.\n”);
}
else {
struct Node* t = front;
if(front == rear) {
front = rear = NULL;
}
else {
front = front->next;
}
printf(“%d kuyruktan cikarildi.\n”, t->data);
free(t);
}
}
void printQueue() {
printf(“%Kuyruktaki elemanlar: “);
struct Node* temp = front;
while(temp != NULL) {
printf(“%d “,temp->data);
temp = temp->next;
}
printf(“\n”);
}
int main(void){
enqueue(5);
enqueue(12);
enqueue(9);
enqueue(1);
enqueue(7);
dequeue();
dequeue();
enqueue(5);
printQueue();
getch();
return 0;
}
2. Ünite - Diziler, Bağlı Listeler, Kuyruklar ve Yığınlar 39

Yararlanılan ve Başvurulabilecek
Kaynaklar
Cormen T.H., Leiserson C.E., Rivest R.L., Stein C. () Int-
roduction to Algorithms, 3rd Edition, MIT Press.
Levitin A. () Introduction to The Design & Analysis of
Algorithms, 3rd Edition, Pearson.
Weiss M.A. () Data Structures and Algorithm Analysis
in C++, 4th Edition, Pearson.
3
ALGORİTMALAR VE PROGRAMLAMA

Amaçlarımız
Bu üniteyi tamamladıktan sonra;
 Ağaç veri yapısında yer alan temel kavramları, ikili ağaçları ve ikili arama ağaç-
larını tanımlayabilecek,
 Ağaçlar üzerinde gezinme yöntemlerini sıralayabilecek,
 AVL ağacı veri yapısını tanımlayabilecek ve ağaç dengesinin korunması için ge-
rekli döndürme işlemlerini açıklayabilecek,
 Yığın ağaçlarının temel özelliklerini ve bu veri yapısında ekleme çıkarma işlem-
lerini özetleyebilecek,
 Özetleme tablosu veri yapısını ve özetleme fonksiyonlarını tanımlayabilecek,
 Özetleme fonksiyonlarında meydana gelen çatışmaları çözümleme yöntemleri-
ni listeleyebilecek
bilgi ve beceriler kazanabileceksiniz.

Anahtar Kavramlar
• İkili Ağaç • Özetleme Fonksiyonu
• İkili Arama Ağacı • Çatışma
• AVL Ağacı • Ayrık Zincirleme
• Yığın Ağacı • Açık Adresleme
• Özetleme Tablosu

İçindekiler

• GİRİŞ
Ağaçlar, Yığın Ağaçları • AĞAÇLAR
Algoritmalar ve Programlama
ve Özetleme Tabloları • YIĞIN AĞAÇLARI
• ÖZETLEME TABLOLARI
Ağaçlar, Yığın Ağaçları
ve Özetleme Tabloları

GİRİŞ
Kitabımızın bu ünitesinde ağaçlar, yığın ağaçları ve özetleme tabloları anlatılmaktadır.
“Ağaçlar” başlığında ağaç veri yapısının tanımı yapılmış ve başlıca ağaç türleri olan
ikili ağaçlar, ikili arama ağaçları ve AVL ağaçları anlatılmıştır. “Yığın Ağaçları (Heap)”
başlığında özel bir ağaç yapısı olan yığın ağaçları gösterilmiş ve bu veri yapısının temel
özelliklerinden bahsedilmiştir. Ünitenin son başlığı olan “Özetleme (Hash) Tabloları” bö-
lümünde ise, verilerin anahtar ve veri çifti şeklinde saklanmasına imkan veren özetleme
tabloları gösterilmiştir.
Ünite genelinde verilen birçok örnek ve alıştırma, konuya ilginizi ve konu genelindeki
hakimiyetinizi arttırmayı amaçlamaktadır. Örnek programları bilgisayar ortamında dene-
meniz ve geliştirmeniz, veri yapıları konusunda pratiğinizi ve bilginizi arttıracaktır.

AĞAÇLAR
Ağaç veri yapısı, verilerin birbirlerine temsili bir Şekil
ağaç oluşturacak şekilde bağlandığı hiyerarşik bir A Basit Bir Ağaç Yapısı
veri modelidir. Bir ağaç düğümlerden ve düğüm- Gösterimi.
leri birbirine bağlayan dallardan meydana gelir.
Ağaç veri yapısı, çizge veri yapısının bir alt kü- B C D
mesidir. Bir çizgenin ağaç olabilmesi için, her iki
düğüm arasında sadece bir yol olmalı, düğümler
arasındaki yolda döngü (cycle) olmamalıdır. E F G
Ağaç veri yapısında bilinmesi gereken başlı-
ca kavramlar aşağıda listelenmiştir:
• Kök (Root): Bir ağacın en üst noktasında bulunan düğümdür.
• Dal (Edge): Düğümleri birbirine bağlayan kenara verilen isimdir.
• Yol (Path): Birbirleri ile bağlantılı dal dizisine yol adı verilir.
• Yol Uzunluğu (Length of a Path): Bir yolu oluşturan dal dizisindeki dal sayısıdır.
• Ebeveyn (Parent): Bir düğümden önce yer alan ve o düğüme bir dal ile bağlı olan
düğüme ebeveyn denir. Kök hariç her düğümün bir ebeveyni bulunmaktadır.
• Çocuk (Child): Bir düğümden sonra yer alan ve o düğüme bir dal ile bağlı olan
düğüm/düğümlere çocuk denir.
• Ağaç Yüksekliği (Height of a Tree): Bir ağacın kökünden ağaçtaki en alt çocuğa
kadar olan yolun uzunluğudur.
• Düğüm Yüksekliği (Height of a Node): Bir düğümden ağaçtaki en alt çocuğa kadar
olan yolun uzunluğudur.
42 Algoritmalar ve Programlama

• Düğüm Derinliği (Depth of a Node): Bir düğümden ağaç köküne kadar olan yolun
uzunluğudur.
Şekil ’de basit bir ağaç yapısı gösterilmiştir. Bu ağacın kökü A düğümüdür. B, C
ve D düğümleri ise A’nın çocuklarıdır. E ve F düğümleri B’nin çocukları, G düğümü ise
D’nin çocuğudur. C, E, F ve G düğümlerinin herhangi bir çocuğu bulunmamaktadır. Kök
düğüm olan A’dan en alt çocuklara uzanan yolun uzunluğu 2 olduğu için, bu ağacın yük-
sekliği de 2’dir. F düğümünün yüksekliği 0, derinliği ise 2’dir.
Bir ağaç veri yapısı, sahip olduğu özellikler ile farklı kategorilere ayrılabilir. Kitabımızda
ağaç veri yapısı başlığı altında ikili ağaçlar, ikili arama ağaçları ve AVL ağaçları işlenecektir.

İkili Ağaçlar (Binary Trees)


İkili ağaçlar, her bir düğümün en fazla 2 çocuğa sahip
Şekil
olabildiği ağaç türüdür. Bu veri yapısında ekleme, silme
Örnek Bir İkili Ağaç A
ve arama işlemleri çok hızlı bir şekilde yapılabilmektedir.
Gösterimi.
Şekil ’de gösterilen ağaçta A ve B düğümleri-
B C nin 2’şer çocuğu, D düğümünün 1 çocuğu vardır. C,
E ve F düğümlerinin ise herhangi bir çocuğu yok-
tur. Bu ağaçtaki her bir düğümün en fazla 2 çocuğu
D E
bulunduğu için, gösterilen ağaç ikili ağaç sınıfına
girer. Şekil ’de gösterilen ağaçta ise, kök olan A
F
düğümünün 3 çocuğu bulunmaktadır. Dolayısıyla,
bu ağacın ikili ağaç olduğu söylenemez.
ÖRNEK İkili ağaca düğüm ekleyen ve düğümleri ekrana yazan program.

#include<stdio.h>
typedef struct TreeNode {
int data;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
TreeNode* createNode(int x) {
TreeNode* t = (TreeNode*) malloc(sizeof(TreeNode));

t->data = x;
t->left = NULL;
t->right = NULL;
return t;
}
void printTree(TreeNode *root) {
if(root != NULL) {
printf(“%d “, root->data);
printTree(root->left);
printTree(root->right);
}
}
int main(void) {
TreeNode *root = createNode(5);
root->left = createNode(6);
root->right = createNode(8);

printTree(root);
getch();
return 0;
}
3. Ünite - Ağaçlar, Yığın Ağaçları ve Özetleme Tabloları 43
Örnek ’de struct kullanımı ile ikili ağaç veri yapısının nasıl tanımlanabileceği gös-
terilmiştir. Tanımlanan ağaç yapısındaki bir düğüm int veri tipinde bir değere, left olarak
adlandırılmış TreeNode göstericisine ve right olarak adlandırılmış TreeNode göstericisine
sahiptir. left ve right olarak isimlendirilen göstericiler, düğümün sol ve sağ çocuklarını
ifade etmektedir. Örnekteki createNode() fonksiyonunun görevi TreeNode tipinde bir dü-
ğüm oluşturmak, printTree() fonksiyonunun görevi ise ağaçta tanımlı düğümleri gezerek
düğüm değerlerini ekrana yazdırmaktır. Ana fonksiyon içerisinde 5 sayısını içeren bir
ağaç düğümü oluşturulmuş ve bu düğüm kök olarak belirlenmiştir. Kökün sol çocuğuna 6
değerini içeren bir düğüm, sağ çocuğuna da 8 değerini içeren bir düğüm yerleştirilmiştir.
Bu örnekteki program çalıştırıldığında, ağaçta yer alan düğümler gezilerek ekrana yazdı-
rılacak, sonuç olarak ekranda “5 6 8” değerleri gözükecektir.

İkili Ağaçlarda Gezinme Yöntemleri


Bir ağacın düğümlerini belirli bir algoritma ve sıra çerçevesinde dolaşma eylemine ikili
ağaçta gezinme adı verilir. Bir bilgisayar programındaki ağaç veri yapısında gezinmenin
düğümlerde arama yapma, düğümleri kullanıcıya gösterme, düğüm değerlerini ekrana
yazdırma gibi çeşitli sebepleri olabilir.
İkili ağaç veri yapısı kendi içerisinde alt ağaçlardan meydana geldiği için, ikili ağaçları
gezinmede özyinelemeli fonksiyonlar kullanılır. İkili ağaçlardaki düğümler dolaşılırken
farklı yöntemler uygulanabilirken, bilgisayar programında bu işi yapabilmek için kabul
görmüş üç gezinme yöntemi bulunmaktadır:
i. Preorder Gezinme (Kök başta)
ii. Inorder Gezinme (Kök ortada)
iii. Postorder Gezinme (Kök sonda)

Preorder Gezinme
Bu yöntemde öncelikle kök, daha sonrasında sol alt ağaç, en son olarak da sağ alt ağaç
üzerinde gezinme yapılır. Bu yöntemi akılda tutmak için “Root – Left – Right” terimini
kullanabiliriz.

Preorder gezinme yöntemi uygulayan özyinelemeli fonksiyon. ÖRNEK

void preorder(TreeNode *root) {


if(root != NULL) {
printf(“%d “, root->data);
preorder(root->left);
preorder(root->right);
}
}

Örnek ’de preorder gezinme yöntemini uygulayan özyinelemeli fonksiyon gösteril-


miştir. Şekil ’deki ikili ağaç bu yöntemle gezildiğinde ekrana yazdırılan düğüm değer-
leri sırasıyla A, B, D, F, E, C olur.
44 Algoritmalar ve Programlama

Inorder Gezinme
Bu yöntemde öncelikle sol alt ağaç, daha sonrasında kök, en son olarak da sağ alt ağaç
üzerinde gezinme yapılır. Bu yöntemi akılda tutmak için “Left – Root – Right” terimini
kullanabiliriz.

ÖRNEK Inorder gezinme yöntemi uygulayan özyinelemeli fonksiyon.

void inorder(TreeNode *root) {


if(root != NULL) {
inorder(root->left);
printf(“%d “, root->data);
inorder(root->right);
}
}

Örnek ’te inorder gezinme yöntemini uygulayan özyinelemeli fonksiyon gösteril-


miştir. Şekil ’deki ikili ağaç bu yöntemle gezildiğinde ekrana yazdırılan düğüm değer-
leri sırasıyla F, D, B, E, A, C olur.

Postorder Gezinme
Bu yöntemde öncelikle sol alt ağaç, daha sonrasında sağ alt ağaç, en son olarak da kök
üzerinde gezinme yapılır. Bu yöntemi akılda tutmak için “Left – Right – Root” terimini
kullanabiliriz.

ÖRNEK Postorder gezinme yöntemi uygulayan özyinelemeli fonksiyon.

void postorder(TreeNode *root) {


if(root != NULL) {
postorder(root->left);
postorder(root->right);
printf(“%d “, root->data);
}
}

Örnek ’te postorder gezinme yöntemini uygulayan özyinelemeli fonksiyon gösteril-


miştir. Şekil ’deki ikili ağaç bu yöntemle gezildiğinde ekrana yazdırılan düğüm değer-
leri sırasıyla F, D, E, B, C, A olur.

İkili ağaçlar üzerinde gezinme yöntemlerini pekiştirmek için Örnek ’deki programa üç
1 temel gezinme yöntemini ekleyiniz. Ana fonksiyon içerisinde 5 elemanlı bir ağaç oluşturup,
oluşan ağaçtaki değerleri tüm gezinme yöntemlerini kullanarak ekrana yazdırınız.

İkili Arama Ağaçları (Binary Search Trees)


İkili arama ağaçları, ikili ağaçların özel bir türüdür. Bu veri yapısında, ikili ağaç özellik-
lerine ek olarak düğümlerde yer alan veriler arasında büyüklük-küçüklük ilişkisi bulun-
maktadır.
İkili ağaç özellikleri taşıyan bir ağacın ikili arama ağacı olabilmesi için ağaçtaki her
düğümün, sol alt ağacındaki tüm değerlerden büyük olması, sağ alt ağacındaki tüm değer-
lerden küçük veya eşit olması gerekmektedir.
3. Ünite - Ağaçlar, Yığın Ağaçları ve Özetleme Tabloları 45
Şekil ’te gösterilen ağaçtaki her bir dü- Şekil
ğümün en fazla 2 çocuğu bulunmaktadır. Do- Örnek Bir İkili Arama
5
layısıyla bu ağaç, ikili ağaç sınıfına girmektedir. Ağacı Gösterimi.
Düğümlerde yer alan veriler incelendiğinde, her
bir düğümdeki değerin düğüme ait sol alt ağaç-
2 8
taki değerlerden büyük, sağ alt ağaçtaki değer-
lerden küçük olduğu görülmektedir. İkili ağaç
özelliklerini taşıyan ve içerdiği veriler arasında 1 6 9
büyüklük-küçüklük kuralını sağlayan bu ağaç,
ikili arama ağacıdır.

İkili arama ağaçlarında inorder gezinme yöntemi uygulandığında, veriler küçükten büyüğe
doğru sıralanmış şekilde gezilmiş olur.

İkili Arama Ağacına Düğüm Ekleme


İkili arama ağacına düğüm ekleme işlemi, ikili ağaca düğüm eklemekten daha karmaşıktır.
İkili arama ağacına düğüm eklenirken, ikili arama ağacı veri yapısının özellikleri korun-
malıdır.
İkili arama ağacına düğüm eklemede, ağacın düğümlerinin değerleri arasındaki bü-
yüklük-küçüklük ilişkisini korumak için eklenecek düğümün yeri tespit edilmelidir. Ağaç
boş ise yeni düğüm, ağacın kökü olarak tayin edilir. Ağaç dolu ise ağacın kökünden yola
çıkılarak, eklenecek düğümün değeri ile kök düğümün değeri karşılaştırılır. Yeni düğü-
mün değeri kökteki değerden büyükse sağ alt ağaca, küçükse sol alt ağaca doğru ilerlenir.
Bu işlem, yeni düğüm için uygun bir yer bulunana kadar tekrarlanır.
Şekil

5 5 İkili Arama Ağacına


Düğüm Ekleme
4 Ekle Örneği.
2 8 2 8

1 1 4

Şekil ’te bir ikili arama ağacına yeni bir düğüm ekleme örneği gösterilmiştir. Bu
örnekte var olan ağaca, 4 değerine sahip yeni bir düğüm eklenmektedir. Ekleme işle-
minde öncelikle kök düğümün değerine bakılır. Kök düğümün değeri 5 olup bu değer
4’ten büyüktür. Dolayısıyla yeni düğümü eklemek için sol alt ağaca gidilir. Sol alt ağacın
kökünde yer alan düğümün değeri 2 olup bu değer 4’ten küçüktür. Yeni düğümü ekle-
mek için sağ alt ağaca gidilir, sağ alt ağaç boş olduğu için yeni düğüm buraya eklenir.
İkili arama ağacını temsil edecek veri yapısı ve ağaca düğüm ekleme fonksiyonu Örnek
’te gösterilmiştir.
46 Algoritmalar ve Programlama

ÖRNEK İkili arama ağacı yapısı ve düğüm ekleme fonksiyonu.

typedef struct TreeNode {


int data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;

TreeNode* insertNode(TreeNode *node, int x) {


if(node == NULL) {
TreeNode *t = (TreeNode *) malloc(sizeof(TreeNode));
t -> data = x;
t -> left = t -> right = NULL;
return t;
}
else if(x > node->data) {
node->right = insertNode(node->right, x);
}
else {
node->left = insertNode(node->left, x);
}
}

İkili Arama Ağacından Düğüm Çıkarma


İkili arama ağacından düğüm çıkarma için öncelikle düğümün ağaçta bulunması gerekir.
Düğüm ağaçta yer alıyorsa, ikili arama ağacı özellikleri korunarak çıkarma işlemi gerçek-
leştirilir.
İkili arama ağacından düğüm çıkarırken incelenmesi gereken üç durum vardır:
i. Çıkarılacak düğümün çocuğu yok ise; düğümün ebeveyninin ilgili göstericisi (left
veya right) NULL yapılır, düğüm hafızadan silinir.

Şekil
İkili Arama
5 5
Ağacından Çocuğu
Olmayan Düğümü 1 Sil
Çıkarma Örneği.
2 8 2 8

ii. Çıkarılacak düğümün 1 çocuğu var ise; düğümün çocuğundan itibaren olan alt
ağaç düğümün ebeveynine bağlanır, düğüm hafızadan silinir.
Şekil
İkili Arama 5 5
Ağacından Tek
Çocuklu Düğüm 2 Sil
Çıkarma Örneği.
2 8 1 8

1
3. Ünite - Ağaçlar, Yığın Ağaçları ve Özetleme Tabloları 47
iii. Çıkarılacak düğümün 2 çocuğu var ise düğümün sağ alt ağacındaki en küçük de-
ğerli düğüm bulunur, bulunan düğüm ile çıkarılacak düğüm yer değiştirilir, dü-
ğüm hafızadan silinir.
Şekil

5 5 İkili Arama
Ağacından Çift
8 Sil Çocuklu Düğüm
Çıkarma Örneği.
2 8 2 6

1 6 9 1 9

Şekil ’te gösterilen örnekte ağaçtan 1 değerine sahip düğüm silinmiştir. Bu düğü-
mün herhangi bir çocuğu olmadığı için, düğüm doğrudan ağaçtan çıkarılabilmektedir.
Şekil ’da gösterilen örnekte 2 değerine sahip düğüm silinmiştir. Bu düğümün bir
çocuğu olduğu için, düğümün çocuğu olan 1 değerine sahip düğüm, düğümün ebeveyni
olan 5 değerine sahip düğüme bağlanmıştır.
Şekil ’de gösterilen örnek, ikili arama ağacından düğüm çıkarma işlemlerinin en
karmaşık olanıdır. Ağaçtan çıkarılacak 8 değerine sahip düğümün iki çocuğu bulunmak-
tadır. Bu yüzden, bu düğümün sağ alt ağacında yer alan, en küçük değere sahip düğüm
bulunmalıdır. Çıkarılacak düğümün sağ alt ağacındaki en küçük değerli düğüm, 6 değe-
rine sahip düğümdür. Bu düğüm çıkarılacak düğüm ile yer değiştirilir. 6 değerine sahip
düğüm 8 değerine sahip düğümün yerine geçer. Daha sonrasında ise 8 değerine sahip
düğüm ağaçtan çıkarılır.

Bu bölümde anlatılan ikili arama ağaçlarından düğüm çıkarma durumlarını göz önüne
alarak, ikili arama ağaçlarından düğüm çıkarma fonksiyonunu geliştiriniz. Yazacağınız 2
program için Örnek ’i temel alıp, bu örnek üzerinden kod geliştirme yapabilirsiniz. Prog-
ramınızdaki ağaca düğüm ekleme, ağaçtan düğüm çıkarma ve ağacı ekrana yazdırma fonk-
siyonlarını deneyip, sonuçlarını gözlemleyiniz.

AVL Ağaçları
İkili ağaçlarda ve ikili arama ağaçlarında ağacın yüksekliği için herhangi bir ölçüt bu-
lunmamaktadır. N adet düğüme sahip bir ikili ağacın yüksekliği en fazla N-1 olabilir. Bu
ağaçlarda yükseklik için bir kısıtlama olmaması, ağaç içerisindeki düğümlerin dengesiz
dağılmasına sebep olabilir. Başka bir ifadeyle, sol alt ağaç ile sağ alt ağaç arasındaki yük-
seklik farkı 1’den fazla olabilir.
AVL (Adelson –Velsky – Landis) ağaçları, ikili arama ağaçlarının özel bir türüdür. Bu Denge Faktörü (Balance
Factor): Bir düğümün sol alt
veri yapısında ağaç içerisindeki denge korunmakta, sol alt ağaç ile sağ alt ağaç arasındaki ağacının yüksekliği ile sağ alt
yükseklik farkı en fazla 1 olabilmektedir. ağacının yüksekliği arasındaki
farka denge faktörü adı verilir.
AVL ağaçlarındaki düğümler için denge faktörü aşağıdaki formül ile hesaplanır ve
dengeli bir ağaç için bu değerler yalnızca -1, 0 ve 1 olabilir:

bf=hLeft-hRight
48 Algoritmalar ve Programlama

Şekil
AVL Ağacı Olan ve bf=-1 bf=-2
AVL Ağacı Olmayan
Ağaç Örnekleri. 6 6

bf=0 bf=0 bf=0 bf=-1


3 8 3 8

bf=0 bf=0 bf=0 bf=1


7 10 7 10

bf=0 9

AVL Ağacı AVL Ağacı Değil

Şekil ’de iki adet ikili arama ağacı gösterilmiştir. Her iki ağaç için de denge faktörleri
hesaplanmış, ilgili düğümün üzerinde kırmızı ile belirtilmiştir. Şekilde verilen ilk ağaçtaki
tüm denge faktörleri 0 ve -1 değerlerinden oluşmaktadır. Dolayısıyla ilk ağaç, bir AVL
ağacıdır. Şekildeki ikinci ağaçtaki denge faktörleri ise -1, 0, 1 ve -2 değerlerinden oluşmak-
Pivot: Denge faktörü 2 veya -2 tadır. Kökte yer alan, 6 değerini taşıyan düğümün denge faktörü -2 olduğu için bu ağaç
olan düğüme pivot adı verilir. AVL
ağaçlarında pivot düğüm üzerinde bir AVL ağacı değildir.
döndürmeler yapılarak denge AVL ağaçları için düğüm ekleme ve düğüm çıkarma işlemleri, ağaçtaki düğümlerin
sağlanır.
dengesini bozabilmektedir. Dolayısıyla bu işlemlerde ağacın dengesini korumak için pivot
düğüm üzerinde çeşitli döndürmeler yapılır.
Şekil
AVL Ağacında Pivot pivot (bf=2 veya -2)
ve Sol-Sağ Alt Ağaçlar.
P

L R

A B C D

Şekil ’da dengesiz durumdaki bir AVL ağacının pivotu (P), sol alt ağaç (L) ve sağ alt
ağaç (R) gösterilmiştir. Şeklin alt tarafında yer alan A, B, C ve D üçgenleri ise sol ve sağ alt
ağaç için süregelen alt ağaçlardır. AVL ağaçları için ekleme ve çıkarma işlemleri anlatılır-
ken aşağıdaki terminolojiden faydalanılacaktır:
• P: Pivot
• L: Pivotun sol alt ağacı
• R: Pivotun sağ alt ağacı
3. Ünite - Ağaçlar, Yığın Ağaçları ve Özetleme Tabloları 49
• A bölgesi: Pivotun sol alt ağacının sol çocuğudur.
• B bölgesi: Pivotun sol alt ağacının sağ çocuğudur.
• C bölgesi: Pivotun sağ alt ağacının sol çocuğudur.
• D bölgesi: Pivotun sağ alt ağacının sağ çocuğudur.

AVL Ağacına Düğüm Ekleme ve Denge Korunumu


AVL ağacına düğüm eklerken, öncelikle düğümün ekleneceği yer bulunur. Düğüm eklen-
dikten sonra oluşan yeni ağaç üzerinde denge faktörleri hesaplanır, ağaçta bir dengesizlik
olması durumunda dengesizliğin olduğu düğüm (pivot) tarafında bir veya iki tane dön-
dürme işlemi uygulanır.
Ekleme işleminden sonra oluşan dengesizlik, dört ayrı şekilde görülebilir:
i. A bölgesine ekleme (LL Imbalance): P’nin denge faktörü 2, L’nin denge faktörü 0
veya 1 iken karşılaşılır, pivot etrafında sağa doğru tek döndürme ile çözülür.
ii. D bölgesine ekleme (RR Imbalance): P’nin denge faktörü -2, R’nin denge faktörü
değeri 0 veya -1 iken karşılaşılır, pivot etrafında sola doğru tek döndürme ile çözülür.
iii. C bölgesine ekleme (RL Imbalance): P’nin denge faktörü -2, R’nin denge faktörü 1
iken karşılaşılır, sağ ve sol çift döndürme ile çözülür.
iv. B bölgesine ekleme (LR Imbalance): P’nin denge faktörü 2, L’nin denge faktörü -1
iken karşılaşılır, sol ve sağ çift döndürme ile çözülür.

Şekil
AVL Ağacına Düğüm Ekleme (LL Imbalance) ve Döndürme Örneği.
bf=1 bf=2 bf=1
12 12 12
bf=1 bf=0 2 Ekle bf=2 bf=0 Döndür bf=0 bf=0
6 16 6 16 4 16
bf=0 bf=1 bf=0 bf=0
4 4 2 6
bf=0
2
bf (P)=2 bf (L)= 1

Şekil ’da bir AVL ağacına 2 değerini içeren yeni bir düğüm eklenmiştir. Oluşan
yeni ağacın denge faktörleri hesaplanmış ve ağacın dengesiz olduğu görülmüştür. 6 değe-
rini içeren düğümün denge faktörü 2 olduğu için, bu düğüm pivot olarak belirlenmiştir.
P’nin denge faktörü 2, L’nin denge faktörü 1 olduğu için ağaçta LL Imbalance vardır. Den-
gesizliğin çözümü için pivot etrafında sağa doğru tek döndürme işlemi uygulanır. Elde
edilen son ağaç dengededir ve AVL ağacı veri yapısı özelliklerini taşımaktadır.
50 Algoritmalar ve Programlama

Şekil
AVL Ağacına Düğüm Ekleme (RL Imbalance) ve Döndürme Örneği.
bf=-1 bf=-2 bf=0
10 10 15
bf=0 bf=0 18 Ekle bf=0 bf=1 Döndür bf=1 bf=0
4 20 4 20 10 20

bf=0 bf=0 bf=-1 bf=0 bf=0 bf=0 bf=0


15 26 15 26 4 18 26
bf=0
18

bf (P)=-2 bf (R)=1

Şekil ’de bir AVL ağacına 18 değerini içeren yeni bir düğüm eklenmiştir. Oluşan
yeni ağacın denge faktörleri hesaplanmış ve ağacın dengesiz olduğu görülmüştür. 10 değe-
rini içeren düğümün denge faktörü -2 olduğu için, bu düğüm pivot olarak belirlenmiştir.
P’nin denge faktörü -2, R’nin denge faktörü 1 olduğu için ağaçta RL Imbalance vardır.
Dengesizliğin çözümü için önce 20 değerini içeren düğüm etrafında sağa döndürme, son-
rasında pivot etrafında sola döndürme işlemi uygulanır. Elde edilen son ağaç dengededir
ve AVL ağacı veri yapısı özelliklerini taşımaktadır.

AVL Ağacından Düğüm Çıkarma ve Denge Korunumu


AVL ağacından düğüm çıkarılırken, ikili arama ağacındaki çıkarma yöntemi izlenir. Dü-
ğüm çıkarıldıktan sonra oluşan yeni ağaç üzerinde denge faktörleri hesaplanır. Ağaçta bir
dengesizlik olması durumunda dengesizliğin olduğu düğüm (pivot) tarafında bir veya iki
tane döndürme işlemi uygulanır.
Çıkarma işleminden sonra oluşan dengesizlik, dört ayrı şekilde görülebilir:
i. A bölgesinden çıkarma (LL Imbalance): P’nin denge faktörü 2, L’nin denge faktörü
0 veya 1 iken karşılaşılır, pivot etrafında sağa doğru tek döndürme ile çözülür.
ii. D bölgesinden çıkarma (RR Imbalance): P’nin denge faktörü -2, R’nin denge faktö-
rü 0 veya -1 iken karşılaşılır, pivot etrafında sola doğru tek döndürme ile çözülür.
iii. C bölgesinden çıkarma (RL Imbalance): P’nin denge faktörü -2, R’nin denge faktö-
rü 1 iken karşılaşılır, sağ ve sol çift döndürme ile çözülür.
iv. B bölgesinden çıkarma (LR Imbalance): P’nin denge faktörü 2, L’nin denge faktörü
-1 iken karşılaşılır, sol ve sağ çift döndürme ile çözülür.
Şekil
AVL Ağacından bf=1 bf=2 bf=0
Düğüm Çıkarma 10 10 5
(LR Imbalance) ve
Döndürme Örneği. bf=-1 bf=0 20 Sil bf=-1 Döndür bf=0 bf=0
5 20 5 3 10

bf=0 bf=0
3 3

bf (P)=2 bf (L)=-1
3. Ünite - Ağaçlar, Yığın Ağaçları ve Özetleme Tabloları 51
Şekil ’de bir AVL ağacından 20 değerini içeren düğüm çıkarılmıştır. Oluşan yeni
ağacın denge faktörleri hesaplanmış ve ağacın dengesiz olduğu görülmüştür. 10 değerini
içeren düğümün denge faktörü 2 olduğu için, bu düğüm pivot olarak belirlenmiştir. P’nin
denge faktörü 2, L’nin denge faktörü -1 olduğu için ağaçta LR Imbalance vardır. Denge-
sizliğin çözümü için önce 3 değerini içeren düğüm etrafında sola döndürme, sonrasında
pivot etrafında sağa döndürme işlemi uygulanır. Elde edilen son ağaç dengededir ve AVL
ağacı veri yapısı özelliklerini taşımaktadır.

Verilen örnekleri bilgisayar ortamında bizzat denemeniz, ağaçlar hakkındaki deneyimini-


zin artmasına katkıda bulunacaktır.

YIĞIN AĞAÇLARI
Yığın ağaçları, bir veri kümesi içerisinde en küçük elemanın hızlıca bulunmasını sağlayan
bir veri yapısıdır. Bu veri yapısında en küçük elemanı bulma, en küçük elemanı silme ve
ağaca eleman ekleme işlemleri hızlıca yapılabilir.
Aşağıda verilen iki özelliği sağlayan bir ikili ağaç, yığın ağacı veri yapısı olarak sınıf-
landırılır:
1. Ağaç bütünlüğü: Ağacın son düzeyi hariç tüm düzeyleri, içerdikleri düğümler
bakımından eksiksiz olmalıdır. Ağacın son düzeyindeki düğümler de soldan sağa
doğru dolu olmalıdır.
2. Heap özelliği: Bir düğümün sahip olduğu değer, düğümün çocuklarına ait değer-
lerden küçük veya eşit olmalıdır.
Şekil
5 3 2 Yığın Ağacı Olan ve
Yığın Ağacı Olmayan
Ağaç Örnekleri.
6 8 10 5 3 8

12 12 7 12 10

Yığın Ağacı Yığın Ağacı Değil Yığın Ağacı Değil

Şekil ’te üç adet ikili ağaç gösterilmiştir. Verilen örnekleri ayrı ayrı inceleyelim:
• Şekilde verilen ilk ağaçta son düzey hariç tüm düzeyler doludur, son düzey ise sol-
dan sağa doludur. Tüm düğümlerdeki değerler, çocuklarına ait değerlerden küçük-
tür. Bu örnekte ağaç bütünlüğü ve heap özelliği sağlandığı için, bu ağaç bir yığın
ağacıdır.
• Şekilde verilen ikinci ağaçta ağaç bütünlüğü sağlanmasına rağmen, heap özelliği
sağlanmamaktadır. 10 değerine sahip düğümün 7 değerine sahip çocuğu olduğu
için, bu ağaç bir yığın ağacı değildir.
• Şekilde gösterilen üçüncü ağaçta son düzeydeki düğümlerin soldan sağa doğru
dolu olmadığı görülmektedir. Dolayısıyla bu ağaç için bir bütünlük söz konusu
değildir. Ağaç bütünlüğü sağlanamadığı için, bu ağaç bir yığın ağacı değildir.

Bu konuda anlatılan yığın ağaçları, minimum yığın ağaçlarını kapsamaktadır. Yığın ağaçla-
rında en büyük elemanı baz alarak da işlem yapılabilir. Ağacın en üst noktasında en büyük

kjhkjhkj
HONOR Pad 8, Tablet Dokunmatik Ekran 12", Pil mAh, Qualcomm Snapdragon , 8 Hoparlör, Mekansal Ses, RAM 6 + GB, Android 12, Google Hizmetleri + WLAN, Mavi

HONOR Pad 8, Tablet Dokunmatik Ekran 12", Pil mAh, Qualcomm Snapdragon , 8 Hoparlör, Mekansal Ses, RAM 6 + GB, Android 12, Google Hizmetleri + WLAN, Mavi

Sevgili SHEIN alışveriş merkezi kullanıcıları:

   Alışveriş merkezi web sitesinin istikrarlı çalışmasını sağlamak ve alışveriş deneyimini iyileştirmek için yakın gelecekte alışveriş merkezi web sitesini güncelleyecek ve bakımını yapacağız. Bu süre zarfında web sitesi normal bir şekilde erişim sağlayamaz, bu durum size rahatsızlık verebilir, anlayışınız için özür dileriz!

Herhangi bir sorunuz varsa, lütfen çevrimiçi müşteri TG ile iletişime geçin: @shein, teşekkür ederim!

BTS, “The Show” Programında &#;DNA&#; Şarkısı İle Program Tarihinin En Yüksek Puanını Alarak 1. Oldu(+Diğer Performanslar)

BTS,&#;DNA&#; şarkısı için ilk ödülünü aldı!

 SBS MTV kanalında yayınlanan  “The Show” programının 26 Eylül tarihli bölümünde,BTS ilk sıra için  APRIL ve Weki Meki grupları ile karşı karşıyaydı.BTS, her kategoride mümkün olan en yüksek skorla toplamda 10, puan aldı.Weki Meki,1, puanla ikinci sırada yer aldı ve  APRIL 1, puanla üçüncü sıraya yerleşti.

BTS ne yazık ki ödülünü almak için programın canlı yayınlanan son bölümüne katılamadı;lakin  “The Show”  programı sosyal medya hesabında BTS grubunun hayranları ARMY&#;lere  ve &#;The Show&#; programına teşekkürlerini sunduğu ve de galibiyetlerini kutladığı bir video paylaştı.

 

BTS ayrıca, Twitter hesabında &#;Tebrikler &#;The Show&#; birinci galibiyeti,teşekkürler&#; yazısıyla J-Hope ve Jimin&#;in olduğu bir video paylaştı.

 

Rap Monster,hayranlarına teşekkür etti ve bu harika skor karşısındaki sürprizini açıkladı.

 

Jin,&#;Birinci galibiyet için teşekkür ederim.ARMY en iyisi!&#; yazısıyla bir fotoğraf paylaştı.

 

Aşağıdaki &#;DNA&#; performansını ve kazananın açıklanma sahnesini izleyin!

 

 

 

“The Show”  programının bu haftaki bölümünde sergilenen diğer performanslar:APRIL, Baikal, BP Rania, D.I.P, ELRIS, FlaShe, Golden Child, GOOD DAY, IZ, Jisoo, Kassy, Lee Gikwang, LOONA grubunun alt grubu Odd Eye Circle, S2, S.I.S, VICTON ve Weki Meki.

APRIL – “Take My Hand”

 

 

Baikal – “Hiccup”

 

BP Rania – “Breathe Heavy”

D.I.P – “A Likely Night”

 

ELRIS – “Pow Pow”

FlaShe – “Popping”

 

Golden Child – “DamDaDi”

 

 

 

GOOD DAY – “Rolly”

 

 

IZ – “All You Want”

 

 

Jisoo – “Vague”

 

 

Kassy – “Let It Rain”

 

 

Lee Gikwang – “What Are You”

 

LOONA Odd Eye Circle – “Girl Front”

 

S2 – “Honeya”

 

 S.I.S – “I’ve Got A Feeling”

 

VICTON – “Unbelievable”

 

Weki Meki – “I Don’t Like Your Girlfriend”

 

Tebrikler,BTS!

Kaynak:Soompi

 

 

 

K-POP haber kategorisi, K-POP dünyasından sıcak sıcak güncel haberlerin bulunduğu haber kategorisidir.

Etiketler: #April #ARMY #Baikal #BP RANIA #BTS #BTS “The Show” Programında ''DNA'' Şarkısı İle Program Tarihinin En Yüksek Puanını Alarak 1. Oldu(+Diğer Performanslar) #D.I.P #dna #ELRIS #flashe #Golden Child #Good Day #IZ #J-Hope #Jimin #Jin #Jisoo #Kassy #Lee Gikwang #LOONA #Odd Eye Circle #Rap Monster #S.I.S #S2 #SBS MTV #The Show #VICTON #Weki Meki

ღ♥ Gizem,18♥ღ ஜ♪RAINBOWBTSYoonhyeTaehyung(V)♪ஜ ۩۞۩''Spero Spera''۩۞۩

nest...

batman iftar saati 2021 viranşehir kaç kilometre seferberlik ne demek namaz nasıl kılınır ve hangi dualar okunur özel jimer anlamlı bayram mesajı maxoak 50.000 mah powerbank cin tırnağı nedir