Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Ahmet Faruk Nacaroğlu
Ahmet Faruk Nacaroğlu
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
40 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler:  C# / VC#/.NET Ahmet Faruk Nacaroğlu
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Başlangıç
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 11.12.2003
Okunma Sayısı : 53716
Yorum Sayısı : 0     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 22.12.2024
Turhal Temizer
Mac OS/X Removing CUDA 22.12.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 22.12.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 22.12.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
C#'ta Özyenilemeli Algoritmalar (Recursion)
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Özyenilemeli algoritmalar tüm dünyada bilgisayar bilimleriyle ilgili bölümlerde veri yapıları ve algoritmalar derslerinde detaylı olarak incelenir. Bu bağlamda biz de makalemizde özyenilemeli algoritmaları geliştirmeyi ve C# ile kodlamayı öğreneceğiz. Önce konunun teorik temelleri üzerinde duracağız. Daha sonra daha iyi anlaşılabilmesi için konu ile ilgili örnekler yapacağız. Makaleyi bitirmeden önce ise klasik döngüler ve özyenilemeli algoritmaları karşılaştıracağız.

Bir alogirtma geliştirirken genelde döngüleri ve karar mekanizmalarını metodların içinde kullanırız. Fakat bazı durumlarda döngüler yerine özyenilemeli algoritmalar kullanmak daha kolay ve anlaşılır olabilir. Özyenilemeli (recursive) metodların püf noktası bu tür metodların bir şekilde tekrar tekrar kendilerini çağırmalarıdır.

Özyenilemeli algoritmalarda problemin en basit hali için çözüm bulunur. Bu en basit duruma temel durum (base case) denir. Eğer metod temel durum için çağırılırsa sonuç dönderilir Daha karmaşık durumlar için metod, temel durumdan yararlanılarak, problemi çözmeye çalışır yani kendini çağırır. Karmaşık durumlar için yapılan her çağrı recursion step olarak adlandırılır.

İsterseniz konunun kafanızda daha iyi canlanması için klasik faktoriyel örneğiyle devam edelim. Sıfırdan büyük herhangi bir n tamsayısının faktoriyelinin formülü şudur:

n! = n * (n-1) * (n-2) * .... * 3 . 2 . 1
Ayrıca 0! ve 1!'in değerleri bir olarak tanımlanmıştır. Mesela 5! = 4*3*2*1 = 120'dir.

Bir sayının, mesela n, faktoriyelini özyenilemeli değilde döngü kullanarak bulmak istersek aşağıdakine benzer bir kod kullanabiliriz:

int faktoriyel = 1;

for( int i = n; i >= 1; i-- )
   faktoriyel *= i;

Kod 1: Döngü ile Faktoriyel hesabı Eğer bu problemi özyenilemeli algoritma yardımıyla çözmek istersek şu noktaya dikkat etmemiz gerekiyor:

n! = n * (n-1)!
Daha açık bir yazım ile;

5! = 5 * 4 * 3 * 2 * 1

5! = 5 * (4 * 3 * 2 * 1)

5! = 5 * (4!)

Aşağıda şekilde 5!in özyenilemeli bir algoritmada nasıl hesablanacağını görüyoruz. Şeklin solunda 5!'den 1!'le kadar her özyenilemeli çağrıdaki neyin çağrılacağı sağda ise sonuca ulaşılana kadar her çağrıda dönen değerler yeralıyor.



C# diliyle özyenilemeli biçimde Faktoriyel hesabı yapan bir metodu aşağıdaki gibi yazabiliriz. Bu fonksiyona int tipinde sayi isimli bir değişken geçiriyoruz. Eğer sayi 1'den küçük veya eşit ise, ki bu temel durumdur, fonksiyon 1 değerini dönderiyor. Diğer durumlarda ise fonksiyonumuz

sayi * Faktoriyel(sayi-1)

değerini dönderiyor.

private static long Faktoriyel(int sayi)
{
    if( sayi <= 1 ) // Eğer temel durumsa 1 dönder
        return 1;
    else                      // Temel durum değilse n * (n -1)! bul.
        return sayi * Faktoriyel( sayi-1 );
}

Kod 2: Özyenileme ile Faktoriyel hesabı

Sıra örneğimizi bir Windows uygulaması olacak biçimde programlayalım. Bunun için öncelikle aşağıda gördüğümüz Form'u tasarlayalım. Metin kutusuna txtSayi ve düğmeye btnHesapla isimleri vermeyi unutmayalım.



Formdaki btnHesapla isimli düğmeye çift tıklayalım düğmenin Click olayına cevap veren metodu yazalım.

private void btnHesapla_Click(object sender, System.EventArgs e)
{
    string sonucMetin="";

    // metin kutusundan değeri al ve int tipine çevir:
    int sayi = Convert.ToInt32(txtSayi.Text);

    for(int i=1; i<= sayi; i++)
        sonucMetin += i + "!= \t" + Faktoriyel(i).ToString() + "\n";

    MessageBox.Show(sonucMetin.ToString(),"Faktoriyel Hesabı");
}

Kod 3: Örnek programda btnHesapla_Click() metodu

Yukarıdaki metod içinde metin kutusuna girilen sayi değerine kadar olan tüm faktoriyeller hesaplanıp ekrana mesaj kutusu içinde yazdırılıyor. Programımızı çalıştırmadan önce programımıza Kod 2'de yeralan metodu da eklemeyi unutmayınız. Örneğimizi 10 değeri için çalıştırırsak aşağıdaki sonucu elde ederiz:



Özyenilemeli Algoritma Örneği: Fibonacci Serisi
Lise ve üniversitelerde matematik derslerinde seriler konusunda gösterilen Fibanocci serilerini programlamak için döngüler yerine özyenilemeli algoritma kullanmak daha kolay ve anlaşılır oluyor. Bu serinin tanımı ise herhangi bir n sayısı için Fibonacci(n)'nin değeri Fibonacci(n-1) ve Fibonacci(n-2)'nin şeklindedir. Tabiki Fibonacci(0) ve Fibonacci(1)'in değeri 1 olarak alınıyor.

Bu serideki sayılar doğada çok sayıda bulunur ve spiral şeklini oluştururlar. Ayrıca art arda gelen iki Fibonacci değerinin oranı 1.68.. şeklindedir. Bu değer altın oran olarak adlandırılır. Özellikle kart postallar, tablolar vb nesnelerin boy ve enlerinin oranları da 1.68.. gibidir. Çünkü insan gözüne çok hoş görünürler. Neyse konumuza devam edelim isterseniz...

Yukarıdaki tanımlardan yola çıkarak Fibonacci serisini hesaplayan metod'ta iki temel durum olacaktır. Bunlar Fibonacci(0) = 1 ve Fibonacci(1) = 1. Ayrıca diğer durumlar için dönen değer, herhangi bir n için, Fibonacci(n-1) ve Fibonacci(n-2)'nin toplamıdır. O zaman metodumuz aşağıdaki gibi olacaktır:

private static long Fibonacci(int sayi)
{
    if( sayi == 0 || sayi == 1) // Eğer temel durumlardan biriyse 1 dönder
        return 1;
    else                      // Temel durum değilse (n-1) + (n -2) bul.
        return Fibonacci( sayi-1 ) + Fibonacci( sayi-2 );
}

Kod 4: Özyenileme ile Fibonacci serisi hesabı Fibonacci serisi ile ilgili aşağıdaki küçük formu tasarlayalım. Sonra gerekli kodları yazıp örneğimizi deneyelim. Formdaki metin kutusunun ismi yine txtSayi olsun. Ayrıca Hesapla etiketine sahip düğmenin ismi btnHesapla olsun. Son olarak arka planı koyu kırmızı olan etiketin ismi de label2 olacak.



Programı tamamlamak için Hesapla düğmesinini tıklandığında gerekli işleri yapacak kodu yazmaya geldi. Ayrıca programın kodunun içine Kod 4 yeralan fonksiyonu da ekleyiniz.

private void btnHesapla_Click(object sender, System.EventArgs e)
{
     // Kullanıcını girdiği değeri al ve int tipine çevir.
     int sayi = Convert.ToInt32(txtSayi.Text);

     // Fibonacci Hesabı yapan fonksiyonu girilen sayi değeri ile çağır.
     // Sonucu label2'ye yazdır.
     label2.Text =Fibonacci(sayi).ToString();
}

Kod 5: Fibonacci örneğinde btnHesapla_Click() metodu Programı test etmek için Fibonacci(15) değerini bulmak istersek aşağıdaki sonucu elde ederiz.



Özyenilemeli Algoritma Örneği: Fibonacci Serisi
Makalemizi bitirmeden önce özyenilemeli algoritmalar ile döngülerden oluşan algoritmaların aralarındaki farklara ve benzerlikte gözatmakta yarar olduğu kanısındayım. İki algoritma türü de akış kontrol mekanizmlarını kullanır. Döngülerde for, while ve do while yapıları kullanılırken özyenilemeli algoritmalarda if, if/else ve switch yapıları yeralır. Aslında hem döngüler de hem de özyenilemeli metodlarda itereasyonlar bulunur. Döngüler doğaları gereği açık bir biçimde iteratiftirler. Fakat özyenilemeli algoritmalarda iterasyon aynı metodun tekrar tekrar kendi içinden çağrılması ile gerçekleşir. Döngülü ve özyenilemeli algoritmalarda göze çarpan diğer bir benzerlikte sonladırıcı testlerin bulunmasıdır. Döngülerde sayacın(counter) belli bir değere ulaşıp ulaşmadığı kontrol edilir ve gerekirse döngü sonlanır. Özyenilemeli algoritmalarda o andaki durumun temel durum olup olmamasına göre işlemler devam edebilir veya sonlanabilir. Son olarak hem döngülerle hem de özyenilemeli algoritmalar ile bilgisayarı sonsuz döngüye(infinite loop) sokabiliriz. Birincisi döngünün sonlanacağı sayaca ulaşmanın imkansız olmasından ikincisi ise temel duruma ulaşamamaktan kaynaklanır.

Aslında özyenilemeli algoritmaları kullanırsak hem daha yavaş hem de hafızada daha çok yer kaplayan programlar yazmış oluruz. Fakat çoğu zaman aynı problemin çöümünü özyenilemeli olarak bulmak daha kolaydır. Ya da döngülerle aynı sonuca varacak algoritmayı düşünmek zor olur. Ayrıca özyenilemeli algoritmaları inceleyince anlamak ve hata ayıklamak daha kolaydır. Bu durumda seçim programcıya kalmıştır. Yalnız işlemcilerin giderek hızlanması, hafıza fiyatlarındaki düşüşü ve programın daha kolay yönetilebilmesinin getirdiği avantajları göz önüne almanızı tavsiye ederim.

Bu makalede özyenilemeli algoritmaları detayları ile inceledik. Konu ile ilgili sorularınızı rahatlıkla sorabileceğinizi belirterek makalemize son verelim.

Makale:
C#'ta Özyenilemeli Algoritmalar (Recursion) C#, Visual C# ve .NET Ahmet Faruk Nacaroğlu
  • Yazılan Yorumlar
  • Yorum Yaz
Bu konu hakkında yayınlanan yorum bulunmamaktadır.
"Yorum Yaz" tabını kullanarak sizde yorumlarınızı yazabilirsiniz.
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor