Stack (Yığın)

Tek taraflı giriş ve çıkışlara açık olan. İlk giren son çıkar LIFO (Last in First Out) mantığı ile çalışan bir ADT örneğidir.
Temelde iki veya üç fonksiyonu bulunur bunlar:
Push -> Stack içerisine bir bilgi koymaya (Stack’in en tepesine koyar)
Pop -> Stack içerisinden bir bilgi almaya (Stack’in en tepesinden alır)
Top -> Stack’in en tepesindeki bilgiyi alır ancak stackten çıkartmaz sadece okur
Stack Yığın
Bu fonksiyonlar sayesinde bir stack kullanılabilir hale gelmiş olur. Aynı fonksiyonlar ile PDA (push down Automata) ‘da tasarlanabilir.

Temel olarak stack, bir array veya Linked List üzerine inşa edilebilirler.
Örnek olarak bir dizi üzerine inşa edilen stack için bir değişken, dizide o anda kaç değer olduğunu tutacak ve her pop işleminden sonra bu değer azaltılırken, her push işleminden sonra arttırılacaktır.

Benzer uygulama linked list üzerinde yapılırsa, pop işlemiyle sondan bir düğüm silinecek veya push işlemi ile sona bir düğüm eklenecektir.

aşağıda basit bir bağlı liste üzerinde stack kullanılan kod örneği verilmiştir:

Yukarıdaki kodlar dev-cpp ile test edilmiştir.

Bağlı liste üzerinden yığın kodlamasının açıklaması (Cansu Hanım’ın sorusu üzerine ekliyorum)

Yukarıdaki bağlı liste kodunu anlamaya öncelikle kullandığımı veri yapısını oluşturan bir düğümü anlayarak başlayalım. Düğüm yapısı için kullanılan kodu ele alırsak:

Yukarıdaki bu kodda bulunan lnode isimli yapı (Struct) iki üyeye sahiptir. Buradaki data isimli int değişkeni, düğüm içindeki verileri tutmak için kullanılmakta ve yine kendi tipinden (lnode) bir gösterici (pointer) ile next isimli bir değişken tanımlanmaktadır. Bu ikinci gösterici değişkenin amacı, kendi tipinden düğümleri göstermek ve bu sayede bağlı listeyi inşa etmektir.

Kodun 8. Satırında ise global bir düğüm değişkeni olan iter tanımlanmış ve NULL olarak içeriği atanmıştır. Bu değişken bağlı listenin ilk elemanını tutmak için kodun geri kalan kısmında kullanılacaktır.

Veri yapımızı tanıdıktan sonra, bağlı liste üzerindeki yığın (stack) fonksiyonlarını anlamaya çalışalım. Bu kodda kullanılan 3 fonksiyon şunlardır:

  • void push(int) -> bu fonksiyon, yığına veri eklemek için kullanılır
  • int pop() -> bu fonksiyon, yığından veri almak için kullanılır
  • void printStack() -> bu fonksiyon ise yığının içeriğini ekrana basmak için kullanılır.

Bu fonksiyonların çalışmalarını anlamaya push fonksiyonu ile başalayalım.

Yukarıdaki kodun, 11. satırında buluna if kontrolü ile, iter göstericisinin ilk değeri kontrol edilmiştir. Buradaki amaç, bağlı listenin ve dolayısıyla yığının içinin boş olup olmadığını anlamaktır. Şayet yığın boşsa (ve dolayısıyla iter’in değeri NULL ise) o zaman hafızada (ram) yeni bir düğüm tanımlanmış ve iter değişkeni bu düğümü gösterecek şekilde atanmıştır (kodun 13. satırı). Ayrıca bu yeni düğümün gösterdiği bağlantı NULL olarak atanmıştır. Bu sayede veri yapımızın son göstericisini NULL olarak ayarlanmış olunur.

Kodun 17. satırında push fonksiyonuna parametre veren ve yığına eklenmek istenen data değişkeni, yeni oluşturduğumuz bu düğümün içerisine veri olarak kaydedilmiş ve ardından yeni bir düğüm oluşturularak bağlı listenin başına eklenmiştir.

Bu fonksiyonun çalışmasını aşağıdaki şekilde hayal etmemiz mümkündür:

Yukarıdaki temsili resimlerde gösterilen 4. durum için, kodun 18. satırında yeni bir düğüm göstericisi tanımlanmış ve bu düğüm göstericisi, bağlı listenin ilk elemanını, kendi next göstericisi ile kodun 19. satırında göstermiştir. Bu sayede bağlı listenin başına yeni bir düğüm eklenmiş ve daha sonraki ekleme işlemleri için bu düğüm boş olarak tutulmuştur. Zaten kodun 11. satırında bağlı listenin boş olup olmadığının kontrol edilmesi ve şayet boş ise yeni bir düğüm eklenmesinin sebebi de budur.

Push fonksiyonu yukarıdaki şekilde, bağlı listeye yeni veri geldikçe ekleme işlemi yapar ve liste içerisine veri eklenerek temsili olarak sola doğru büyür. Listenin son elemanı her zaman için NULL değerindedir ve listeye yeni eklenen değerler soldan eklenir.

Kodun 44. satırına kadar olan main fonksiyonu içerisinde bulunan push fonksiyonları çalıştırıldığında bağlı listenin hali aşağıdaki şekli alır:

Push fonksiyonunun çalışmasına baktıktan sonra sıradaki fonksiyonumuz olan pop fonksiyonunu inceleyelim:

pop fonksiyonu, iter ile gösterilmekte olan düğümden (node) bir sonraki düğümün verisini döndürmekte ve iter göstericisini sağa doğru ilerletmektedir.

kodun 28. satırındaki free fonksiyonunun amacı, bu ilk başta tutulan düğümün hafızadan (ram) kaldırılması ve gereksiz yere yer kaplamamasıdır.

Son olarak yığının (stack) içeriğini ekrana basan fonksiyonumuz olan printStack fonksiyonunu incelersek:

bu kodda, temp isminde geçici bir gösterici, iter’in gösterdiği ilk elemandan başlayarak bağlı listenin sonuna kadar olan bütün elemanları sırasıyla ekrana basmaktadır.

Yorumlar

  1. cansu

    programı tam olarak anlayamadım
    mesela push 10 dedik ama burdaki ekran çıktısı atıyorum 198556-10
    oluyo
    push 20 de ise 1985-20-10 şeklinde bu neden kaynaklanıyo yardımcı olabilirmisiniz

  2. Şadi Evren ŞEKER Article Author

    program, başta bulunan ve iter tarafından tutulan boş düğümü (node) de basıyor. Şayet bu tip baştaki anlamsız sayıları görmek istemiyorsanız, kodun 33. satırındaki
    lnode *temp = iter;
    kodunu aşağıdaki şekilde değiştiriniz:
    lnode *temp = iter->next;
    Bu defa yığının ilk elemanından başlanarak basılır ve aslında daha başta olan ve içerisinde veri olmayan boş düğüm basılmaz.

    Yukarıdaki yazının içerisine kodun nasıl çalıştığını açıklayan bir kısım eklemeye çalışayım belki yardımcı olur.

    başarılar

  3. serhat

    ben bu stack ve listelemeyi kullanarak bir dosyadan okunan 2 sayıyı carpmayı nasıl yapabiliriz. yada fgetchar ı kullanarak . yani ınput dosyasında olan iki sayıyı 2 ayrı listeye atıp bu sayıları çarpacak ve sonucu da br lsitede tutacak . yardımcı olursanız sevınırm

  4. Şadi Evren ŞEKER Article Author

    Sorunuzu doğru anladıysam, çok büyük iki sayı, dosyalarda bulunuyor ve siz de bu dosyalardan her seferinde bir karakter okuyorsunuz. Dosyadan, sayının tamamı okunamayacak kadar büyük sayı olduğu için bu yolla okuyup sayıları nasıl çarpacağımızı soruyorsunuz.

    Bakın dosyalardan birisindeki örnek sayı aşağıdaki gibi olsun:

    1231432142121312312

    diğerinde de aşağıdaki sayılar olsun
    3432423423412312714

    Şimdi bu iki sayıyı , C dilinde bir değişkende tutamayacağımıza göre, bir yol bulup bunları çarpmalıyız. İlk okulda öğrendiğimiz üzere çarpma işlemine son haneden başlanır ancak ne yazık ki son hane, dosyanın sonunda bulunuyor ve dosyayı okumaya başladığımızda elimize ilk hane geliyor.

    Olsun, bu durumu tersine çevirmek mümkün. Veri yapılarından yığın (stack) tam da bunun için tasarlanmış. Başlıyoruz dosyadan okuduğumuz sayıları yığına (stack) koymaya.

    Neticede stackin en üstünde, çarpılacak olan sayıların son haneleri bulunuyor.

    Örneğin ilk yığının en üstünde, son sayı olan 2, ikinci yığında ise son sayı olan 4 bulunuyor.

    Bu iki sayıyı çarpıp elde var bilgisi ile sonraki sayılara geçiyoruz ve böylece bütün sayılar çarpılana kadar devam ediyoruz.
    Örneğimizden devam edecek olursak, 2x4 = 8 (elde var 0). 8'i bir kenara yazıp sonraki sayılara geçiyoruz (stackten pop ediyoruz)

    1x1 = 1 (elde var 0 )
    3x7 = 1 (elde var 2 )
    2x2 = 4 + 2 = 6 (elde var değeri buraya eklendi)
    Görüldüğü üzere elde var değeri için ilave bir değişken tutulması gerekiyor. Ayrıca yukarıdaki sonuçlar da bir listede durabilir.
    Şimdiye kadar olan sayılar için temsili liste:
    Head -> 6 -> 1 -> 1 -> 8 -> NULL

    Sürekli başa ekleme yapılan (insert front) yukarıdaki şekilde bir liste, sonucu tutmak için uygundur. Veya bu veriyi işlemeyecekseniz doğrudan ekrana basmak gibi yollar da bulunabilir.

    Bilemiyorum açıklayıcı oldu mu ama anlaşılmayan birşey olursa daha detaylı anlatabilirim.

    başarılar

  5. serhat

    yardımcı oldunuz teşekkürler.bu stack yerine linked list e atıp karakterleri snra carpma işlemi yapan örnek ufak bir kod var mı peki elinizde desem cok mu olmus olurm :d

  6. Şadi Evren ŞEKER Article Author

    Aslında stack ve linked list farklı yapılar değiller. Yani olmaları gerekmiyor. Linked list, stack veya queue olarak kullanılabilir. Yukarıdaki anlattığım algoritmayı linked liste uyarlayabilirsiniz.
    Hazır kod yok ne yazık ki. Ancak bağlı liste kodlarına (linked list) bir göz atmanızı tavsiye ederim. Aşağıda bağlantıyı veriyorum :
    http://www.bilgisayarkavramlari.com/2007/05/03/linked-list-linkli-liste-veya-bagli-liste/

    Başarılar

  7. serhat

    çok olduğumun farkındayım ama lined listlerle yaparken karaker karakter okumak için fgetchar kullanmak lazım diye biliyorum . bu fgetchar ın kullanımını anlatablir misinziz rica etsem ?

  8. hayat

    merhabalar
    5+4*7+8 bu stringi kaakter karakter okuyup rakamları bir classa operatörleri ayrıbir classa yerleştiren daha sonra operatör sınıfından ilk operatörü alıp rakam sınıfından iki rakam alan (başta + operatörü var diğer class da da 7,8 alır toplar sonuc 15 dahasonra 15 i tekrar sayı sınıfına atar sonra operatör sınıfından * yı alır diger class dan 15 ve 4 alır bu operatör sınıfında hiç elemn kalmayana kadar devam eder sonuc 65 olnca sonucu geri döndürür)bunu stack ile nasıl yapabiliriz ... yardımcı olursanız sevinirim

  9. Şadi Evren ŞEKER Article Author

    bu meşhur bir ödev sorusudur. yalnız soru ile ilgili hatalarınız var. Algoritma tasarımınızda işlem önceliğini göz ardı etmişsiniz. Örneğin bahsettiğiniz şekilde işlem yapılınca sonuç 65 çıkıyor.

    Oysaki ilk yapılması gereken işlem 4*7 ve ardından toplama işlemleri. Yani sonuç 65 değil, 28 + 5 + 8 = 41 olmalı.

    Sorunun çözümü için ön işlem hesaplaması (prefix calculation, veya literatürde polonya yazımı hesaplaması (polish notation calculator) olarak da geçer) anlamanızda yarar var. Bu gösterimde sayılar prefix olarak aşağıdaki şekilde yazılıp hesaplanır:

    * + 2 3 4 = 10 (önce * 2 3 sonra + 4 işlemi yapılır)

    Benzer gösterim de son işlem hesaplaması (postfix calculator veya ters polonya yazımı hesap makinesi (reverse polish notation calculator) ) şeklinde geçer ve işlemler aşağıdaki şekilde yazılır:

    2 3 4 + * = 11 (önce 2 * 4 sonra + 3 işlemi yapılır)

    Gelelim sizin probleminize,
    infix gösterimi ile yazılan (yani işlemlerin (operators), sayıların arasında bulunması durumu) denklemler için aşağıdaki gibi stack (yığın) yapısı izlemeniz gerekiyor:

    Sizin verdiğiniz örnek üzerinden gidelim:

    5 + 4 * 7 + 8

    Öncelikle iki ayrı yığın (stack) tutuyoruz. Birisi sayıları (S1 olarak göstereceğim), diğeri ise işlemleri (S2 olarak göstereceğim ) barındırıyor.

    S1 --> 5 4
    S2 --> +

    İşlemin ilk 3 sembolüne baktığımızda yukarıdaki gibi bir durum ortaya çıkıyor. Yani basitçe 5+4 kısmına baktık. Devam edelim:

    S1 --> 5 4 7
    S2 --> + *

    Bu aşamada, * ve + işlemleri üst üste geldi. Şayet üst üste gelen işlemlerden öncelikli olan yukarıda ise yığına (stack) yerleştiriyoruz. Yani şu anda * işlemi + işleminden öncelikli olduğu için işlemi yapmadık ama yığına yerleştirdik.

    Bir sonraki adımda, sıradaki işlem + olarak gelecek ( denklemin sonunda bulunan + 8 kısmı). Bu durumda + işlemi *'dan düşük öncelikli olduğu için yığına konulamaz. Bunun yerine yığındaki işlem yapılır.

    S2 yığınında en üstte bulunan işlem (pop sonucu gelecek olan terim) * işlemidir. Bunu pop ediyoruz. Ayrıca S1 yığınından da iki değeri pop ediyoruz: 4 ve 7
    İşlemi yapıyoruz :

    4 * 7 = 28

    çıkan sonucu S1'e yerleştiriyoruz:

    S1 --> 5 28
    S2 --> +

    son durumda gelen yeni değere bakalım : + 8
    Yine yerleştirme yapmıyoruz çünkü yeni işlem + olarak geldi. İşlem yığını olan S2'de ise aynı önceliğe sahip + işlemi bulunuyor. Bu durumda yığında bulunan işlemi yapabiliriz:

    S1 --> 33
    S2 --> boş

    Şimdi gelen yeni terimleri yerleştirelim:

    S1 --> 33 8
    S2 --> +

    Son olarak denklem bittiği için stackteki işlemleri yapıyoruz:

    33 + 8 = 41 olarak sonuç bulunuyor.

    başarılar

  10. hayat

    hocam öncelikle teşekkür ederim verdiğiniz bilgiler için.benim sorunum aslında algoritmada değil
    kodda ben sayıları bir classa operatorleri diğer classa atmayı beceremedim c++ da. yardımcı olursanız gerçekten cok makbule geçer çünkü gerçekten bayadır uğraşıyorum

  11. Şadi Evren ŞEKER Article Author

    class tasarımınızda bir hata olması çok yüksek ihtimal. sınıf tasarımınızı ve metot prototiplerinizi yollarsanız sizin için inceleyerek hatayı bulabilirim. Örneğin class diagram ve fonksiyonlarınızın parametrelerini yollayabilirsiniz.

    başarılar

  12. SEMA

    Merhabalar,stack yapısını kullanarak labirent yapmaya çalışıorum,bağlı liste ile oluşturlmuş bir stack yapsıı ne demek o şekilde yazmam gerekmiş?yiğina giriş noktasından itibaren izlenen yol eklenecek,giriş noktası sol üst köşe olcakmış bu kodu nasıl yazarım ben şöyle düşündüm
    int maz[0][0]=Yigin.indis dizinin içine ne yazmam gerk ki 0 0 dedim ama sol üst köşede bir yer olcak belki bu nokta bir duvar,sırayla aratmam mı gerk acaba,yardımcı olursanz çok sevinirim.

  13. cem

    Benim anlamadigim nokta stack veri yapisini kendimiz mi tasarliyoruz yoksa programlama dillerinin icinde geliyor mu?(push pop gibi fonksiyonlar yani)

  14. Şadi Evren ŞEKER Article Author

    Kendimiz her zaman için tasarlayabiliriz. Örneğin yukarıdaki yazıda, C dili için tasarım verilmiştir. Ayrıca bazı dillerde stack yapısı hazır da sunulmaktadır. Örneğin JAVA, C# gibi dillerde hazır bulunur. Ancak standart C dilinde hazır bir stack yapısı bulunmaz. Kullanılmak istendiğinde kodlanmalıdır.

    java dilinde hazır stack yapısı için java.util.stack kütüphanesi kullanılabilir. Bu yapının kullanıldığı bir uygulamaya aşağıdaki bağlantıdan ulaşabilirsiniz:

    http://www.bilgisayarkavramlari.com/2011/11/04/labirentte-yol-bulma-kodu/

  15. Şadi Evren ŞEKER Article Author

    yığıt ile stack mi kastediliyor acaba? yani yığıt ile kastedilen heap ise farklı bir uygulama gerekir ancak stack ise, bu yazıda bulunan örnek kodların işinizi görmesi gerekir. Basitçe bir yığın (stack) dizide veya bağlı listede tutulabilir (linked list) ayrıca aktarma işlemine gerek yoktur. Yukarıdaki örnek kodda bu tutma işleminin nasıl yapıldığı anlatılmıştır. Şayet dizi temelli bir yığında (stack) tutuyor ve bağlı listeye (linked list) aktarmak istiyorsanız aşağıdaki gibi bir kod işinizi görür :

    while(!stack.isEmpty())
    liste.add(stack.pop());

    Başarılar

  16. muhendis_adayi

    mrb hocam yukarıda yığıtı link-list ile gerceklemissiniz link-list yerine bunu eleman sayı belli olan ornegin double tipinde 100 elemanlı bir diziyle gerceklemek istesek dizinin dolu veya bos oldugunuda denetleyerek nasıl olur ugrastım ama yapamadım diziyi bosaltamıyorum push tada pop tada sorun yasadım yardımcı olursanız sevinirim

  17. muhendis_adayi

    Hocam cevap bekliyorum 2 gün sonra 2 gün sonra 2.vizeler baslıyo ve dizilerle push pop gercekleme cıkacak kafamda tasarımını bir turlu olusturamadım hocanın istediği dizi[100] elemanlı olsun ornegin bunun doluluk bosluk durumlarınıda inceleyen C programı

  18. muhendis_adayi

    ben boyle bisey yazdım hocam

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    
    #include "stdio.h"
    #define MAXVAL 100
    double val[MAXVAL];
    int sp = 0;
    void push (double f){
          if (sp==100)
              printf("yıgıt daha eleman alamaz");
          else{
     
              val[sp] = f;
              ++sp;
    	  } 
     
      }
     
    double pop(void){
    	double w;
    	if (val[0] == '*'){
    	     printf("yıgıtta eleman kalmadı");
     
    	}
    	else {
     
    	      w = val[sp-1];
    	      val[sp-1] = '*';
    	      --sp;
    	     }
    return w;
    }
     
    int main(void)
    {
    	double p;
    	push(3);
    	push(5);
    	push(9);
    	push(7);
    	p = pop();
    	printf("%0.f",p);
    	p= pop();
    	printf("%0.f",p);
    	p = pop();
    	printf("%0.f",p);
        p = pop();
    	printf("%0.fn",p);
        p = pop();
    	printf("%0.f",p);
        return 0;
    }

    ama yıgıtta eleman kalmadıgı zaman yıgıtta eleman kalmadı0 donuyo sonundaki sıfır niye geliyo orayı anlayamadım

  19. Şadi Evren ŞEKER Article Author

    Anladığım kadarıyla dizi ile yığın kodlamak istiyorsunuz. Basit bir kodlamayı aşağıdaki şekilde yapabilirsiniz:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    #define limit 100
    double a[limit];
    int sayac = 0;
     
    int push(double eklenen){
       if(sayac<limit){
          a[sayac++] = eklenen;
          return 1; // basarili
       }
       return -1; // hata limit dolu daha fazla eklenemez
    }
     
    double pop(){
       if(sayac > 0)
        return a[sayac -- ];
      return -1; // hata stack boş olduğu halde pop
    }
  20. Şadi Evren ŞEKER Article Author

    kodunuzdaki hataya gelince. pop fonksiyonunda double w tanımlamışsınız. bu değişkene değer atamadığınız için kullandığınız compiler muhtemelen içerisine 0 atıyor.

    pop fonksiyonunuzda içinde değer kalmayınca ekrana değer kalmadı yazdırıyorsunuz (if'e giriyor) ancak sonra return w yapıyorsunuz. Bu durumda içinde değer olarak 0 olan değer döndürülüyor ve main fonksiyonunda ekrana printf ile yazılıyor dolayısıyla sonda gördüğünüz 0 değeri buradan geliyor.

    Başarılar

  21. muhendis_adayi

    double pop(){
    if(sayac > 0)
    return a[sayac -- ];
    return -1; // hata stack boş olduğu halde pop

    Hocam burda yazdıgınız kodda if deyiminden çıktıktan sonra return -1 dondurecek yanlıs mı dusunuyorum

    if(sayac > 0)
    return a[sayac -- ];
    else
    return -1; // hata stack boş olduğu halde pop

    else koymamız gerekmez mi?

    yine yazdıgınız kodun bu kısmındada aynı sey aklıma takıldı

    if(sayac

  22. Şadi Evren ŞEKER Article Author

    if deyiminden sadece hata olduğunda çıkacağı için bir sorun yok. Kod doğru. Yani if doğru ise zaten return yapılacak ve alttaki sizi endişelendiren return satırı hiç çalışmayacak. O satırın çalışması sadece hata olduğunda mümkün ki biz de zaten bu durumda -1 döndürmek istiyoruz. Benzer durum diğer fonksiyon için de geçerli.

    Başarılar

  23. massi

    Kullanıcı isterse Veri Yapıları dersini A ve B grubu olarak ikiye ayıracaktır. A grubunda tek numaralı öğrenciler ve B grubunda çift numaralı öğrenciler olacaktır. Veri Yapıları dersini iki gruba ayırmak için gerekli yığın fonksiyon ve işlemlerini yazınız

    burda tek ve çift numaralı öğrencileri nasıl listeleyecez çünkü top un tek veya çift olduğunu bilmiyoruz...

  24. Şadi Evren ŞEKER Article Author

    Top fonksiyonu her zaman için size en üstteki değerin bilgisini döndürür, top'un tek veya çift olduğunu biliyor olmanız gerekir bunun için yığın (stack) de bulunan top() fonksiyonunu kullanabilirsiniz. Şayet top() fonksiyonu tanımlı değilse o zaman pop() yapılıp değere bakılır ve ona göre ikinci bir yığına (stack) konulabilir.
    Kabaca s1,s2 ve s3 olsun ve bütün öğrenciler s1'de bulunsun, s2 çift ve s3 ise tek öğrencileri koyacağımız yığınlarımız (stack) olsun:

    1
    2
    3
    4
    5
    6
    
    ogrenci temp;
    while(temp = s1->pop())
       if(temp.no %2 == 0)
          s2->push(temp);
       else
          s3->push(temp);

    Yani kaynak yığından veri alınacak tek mi diye bakılacak ona göre bir yığına push edilecektir.

  25. blgsyr_muhendis

    Bağlantılı liste kullanılarak yapılan yığın ile soyut veri yapısı tanımlayınız.Yığının
    her bir düğümünde öğrencinin numarası, adı, soyadı ve bölümü bilgileri tutulacaktır.Ben yıgında ogrencının numarasını adını soyadını bolumu bılgılerını nasıl tutacagım.Yıgındakı dugume ogrencını bılgılerını eklemek ıstesem push(no,ad,soyad,bolum)bırden fazla yazılabılır mı bıraz bu konuda bılgılendırebılırmısınız?

  26. Şadi Evren ŞEKER Article Author

    Evet yazılabilir. Yani yığındaki her bir düğüm veri yapısı olarak bir sınıftan türeyen nesne olacak.

    1
    2
    3
    4
    5
    
    class dugum{
      dugum *next;
      int no;
      char *ad;
    };

    şeklinde düşünebilirsiniz. Buradaki her düğüm elemanının bir sonraki düğümü gösteren bir göstericisi (pointer) bulunacağını kabul ediyoruz.
    Ayrıca push fonksiyonu bu sınıftan bir eleman alabilir

    1
    2
    3
    
    public void push(dugum yeni){
     // ekleme işlemleri yazıda anlatıldığı gibi yapılabilir
    }

    Sanırım bu şekilde yaparsanız sorununuz çözülecektir. Ayrıca push fonksiyonuna verilecek olan parametre için artık veriyi nereden okuyorsanız (dosya, klavye vs.) bu okuma işleminden hemen sonra bir nesne oluşturup fonksiyona parametre olarak geçirmeniz gerekir.

  27. cem

    Merhaba,

    typedef struct lnode{
    int data;
    lnode * next;
    };

    buradaki lnode * next; kismini anlamadim. Struct icinde Struct tanimlamak konusunu bilmiyorum. Bu konuya kimse aciklik getirmemis ama benim gibi acemilerin kafasini karistiriyor. Neden basitce int * next; demedik?

  28. bilgisaybilgisay

    Cem Bey,

    Veri yapılarının (ve dolayısıyla veri yapıları dersinin de) ana konusu bir veri ünitesi ile diğeri arasında hafızada ilişki kurmaktır. Yukarıdaki lnode yapısında (struct) bir int değer dururken bir de yine kendi tipinden farklı yapılara ulaşmayı (ve bağlamayı) sağlayacak gösterici (pointer) durmaktadır. Bu sayede yapı (struct) kendi tipinden diğer yapılara bağlanabilmektedir.

    int *next denilirse yapıların birbirine bağlanması mümkün olmaz, yukarıdaki yapıdan bir tane tanımlanır ve o yapının bir int bir de int* tipinden iki üyesi olur.

  29. ugur

    Hocam sizinle mail yolu ile iletişime geçmiştim konu başlığı altında yorum yaparsanız yardımcı olurum demiştiniz c programlama dilini öğrenmeye çalışıyorum bir ödevim vardı.yığın ve kuyruk yapılarını dizi ve bağıntı şeklinde kodlama ödevi yığın yapısını tamamladım ama kuyruk yapısında bir hata var ve bağlı liste şeklinde yapamadım yardımınızı isticektim

  30. Quacquarelli Symondsgt
    struct kuyruk{
                int sayi;
                char ad[10];
                struct kuyruk *sonrakiPtr;
    };
    typedef struct kuyruk Kuyruk;
    typedef struct kuyruk *kuyrukPtr;
    kuyrukPtr yer_ayir(){
                kuyrukPtr p;
                p=(kuyrukPtr)malloc(sizeof(struct kuyruk));
                return (p);
     
    }
    int bosmu2( kuyrukPtr basPtr){
                return basPtr==NULL;
    }
    void ekle(kuyrukPtr *kPtr,kuyrukPtr *sPtr,int veri,char *isim){
     
     kuyrukPtr temp;
                temp=yer_ayir();         
                temp->sayi=veri;
                strcpy(temp->ad,isim);
                temp->sonrakiPtr=NULL;
                if(bosmu2(*sPtr)){
                            *sPtr=temp;
                }
                else
                (*kPtr)->sonrakiPtr=temp;
                *kPtr=temp;
    }
    void sil(kuyrukPtr *sPtr,int *px,char *isim){
     
                kuyrukPtr gecici;
                gecici = (*sPtr);
     
                (*sPtr) =gecici->sonrakiPtr;
                *px = gecici->sayi;
                strcpy(isim,gecici->ad);
                free(gecici);
                printf("%d.%s silindi\n",*px,isim);
    }
    void yazdir(kuyrukPtr kPtr){
                printf("kuyruktaki veriler\n");
                while(kPtr != NULL )
                {
                            printf("%d.%s\n",kPtr->sayi,kPtr->ad);
                            kPtr= kPtr->sonrakiPtr;
                }
    }
    void sec()
    {
                printf("\n1 ekleme\n");
                printf("2 silme\n");
                printf("3 yazdirma\n");
                printf("4  cikis\n");
    }
     
    int main(){
                kuyrukPtr sPtr=NULL;
                kuyrukPtr kPtr=NULL;
                int sayi,i,x;
                int secim;
                char isim[10];
                char ad[10];
                printf("bir secim yapiniz\n");
                sec();
                scanf("%d",&secim);
                while(secim !=4){
                            switch(secim){
                            case 1:
                            printf("isim giriniz:\n");
                            scanf("%s",isim);
                            printf("numara giriniz:\n");
                            scanf("%d",&sayi);
                            ekle(&amp;kPtr,&sPtr,sayi,isim);
                            break;
                            case 2:
                            sil(&sPtr,&x,ad);
                            break;
     
                            case 3:
                    yazdir(sPtr);
                            break;
                            default :
                                       printf("yanlis secim\n");
                                       break;
                            }
                            sec();
                            scanf("%d",&secim);
                }
                system("pause");
                return 0;
    }
  31. yusuf

    kuyruk ve yığın yapılarını kullanarak c/c++ programa dillerini kullanarak aşağıdaki yöntemlerlegerçekleştiiniz?

    1-)dizi yapısını kullanarak
    2-)bağlantılı liste kullanarak
    hocam sunları yapabılırmısınız gerçekten çok yardımcı ve size şükranlarımı sunarım hoca ödev vermıste ve ek puan alacaz sınavdan yardımcı olsanız çok iyi olur şimdiden cok tşk ederım teslım etmemız bugun saat 17:00 kadar hocam tşkler klay gelsın

  32. Taha

    Hocam iyi günler.Bize verilen ödevde ilk önce öğrencinin adı,soyadı,memleketi ve numarasını giricez ondan sonrada bir öğrenci 'nin bilgisini ya yeniliyeceğiz yada o öğrenciyi listeden kaldıracağız.bu programda pop yada push komutunu nasıl kullanabilrim?(belli bir yere kadar geldim ama o komutların tam nasıl kullanıldığını anlayamadım).

  33. Emre

    Hocam, umarım yardımcı olursunuz.
    Şöyle bir ödevim var. Bir yazarın kitabını temin ettim fakat öğrenemedim ben bunu.
    Acil yetişmesi de gerekiyor bu ödevin ve 2 senedir geçemedim. Yardımcı olursanız sevinirim.

    Soru;
    C++ programlama dili ile yazacağınız program İkili Arama Ağacı ve Tek Yönlü Bağlı Liste veri yapısı kullanmalıdır. İkili Arama Ağacı veri yapısının içerisinde Bağlı liste veri yapısı bulunmaktadır. Program çalıştığında bir txt dosyasından verileri almalıdır. Örnek txt dosyası aşağıda verilmiştir. Txt dosyasından alınan ilk satırdaki boşluğa kadar olan kısım ağacın verisini boşluktan sonraki kısım ise ağacın içindeki listenin verisini belirtmektedir. Okunan her bir satırda eğer ağaçta ilgili düğüm yoksa ağaç düğümü oluşturulmalıdır ve liste verisi eklenmelidir, eğer ilgili ağaç düğümü varsa ilgili düğümün sadece liste verisi listenin sonuna eklenmelidir. Düğümler oluştuktan sonra oluşan ağaç inorder, preorder ve postorder şeklinde ekrana yazılmalıdır. Yazdırılma işleminde her düğüm ekrana yazdırılacağı sırada düğümün içerisinde barındırılan liste baştan sona kadar ekrana yazdırılmalıdır.

    - Dosya Formatı

    Anakartlar AMD
    Bellekler DDR3L
    Bellekler DDR4
    Islemciler AMD
    Bellekler DDR
    Bellekler DDR2
    Anakartlar Intel
    Bellekler DDR3
    Islemciler Intel

    - İlgili yazım formatı aşağıda verilmiştir...

    Inorder Yazım

    Anakartlar

    AMD Intel

    Bellekler

    DDR3L DDR4 DDR DDR2 DDR3

    Islemciler

    AMD Intel

    Tasarlayacağınız sınıf yapısı aşağıdaki gibi olmalıdır.

    Düğüm Sınıfı(Bağlı Liste)
    Düğüm Sınıfı(Ağaç)
    Ağaç Sınıfı
    Bağıl Liste Sınıfı (Dizi ile gerçekleştirilmemelidir.)
    Test Programı (Sınıf değil, Uygulamanın kendisi)
    Düğüm verisi ağacın içerisindeki veriyi temsil etmektedir.

    - Oluşturulacak bütün nesneler Heap Bellek Bölgesinde oluşturulmalı ve program süresince ve kapandığında kesinlikle çöp oluşmamalıdır. Sınıfların alt alanları private olmalı ve bu alt alanlara gerektiğinde erişim metotlar yardımıyla yapılmalıdır. Programda goto kullanılamaz.

  34. meryem

    hocam java ile veri yapıları anlatımına ciddi ihtiyac olduğunu düşünüyorum. internette yeterli bir anlatım yok acaba siz ne zamana yapacaksınız merak ile bekliyorumm

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir


× 2 = iki