Linked List (Linkli Liste veya Bağlı Liste)

Bağlı liste herhangi bir tipten node’ların (düğümlerin) yine kendi tiplerinden düğümlere işaret etmesi (point) ile oluşan zincire verilen isimdir. Buna göre her düğümde kendi tipinden bir pointer olacak ve bu pointerlar ile düğümler birbirine aşağıdaki şekilde bağlanacaktır.

bagli liste
Linked List’in avantajı, hafızayı dinamik olarak kullanmasıdır. Buna göre hafızadan silinen bir bilgi için hafıza alanı boşaltılacak veya yeni eklenen bir bilgi için sadece o bilgiyi tutmaya yetecek kadar hafıza alanı ayrılacaktır.

Yukarıdaki figürde görülen bağlı listeye çok benzeyen ve yine çok kullanılan bir bağlı liste uygulaması da çift bağlı liste (doubly linked list) uygulamasıdır.
Çift bağlı liste

Buna göre her düğüm, hem kendinden öncekine hem de kendinden sonrakine bağlanır, bu sayede liste üzerinde ileri ve geri ilerlemek mümkündür.

Yukarıdaki şekilde, sırasıyla, Tek bağlı liste (singular linked list), çift uçlu bağlı liste (double ended linked list), çift bağlı liste (doubly linked list) ve dairesel bağlı liste (circular linked list) görülmektedir.

Listelerin üzerinde işlem yapılırken, dolaşıcı (iterator) şeklinde bir gösterici tanımlanır. Bu dolaşıcı veri aranması, ekleme veya silme gibi işlemler sırasında listenin ilgili elemanına kadar gidilmesini sağlar. Listenin ilgili elemanına gidildikten sonra silme veya ekleme gibi işlemler yapılırken göstericilerde (pointers) yapılan değişikliklerin, listeyi etkilememesini sağlar.

Örneğin bir bağlı listeye yeni bir eleman eklenmesi sırasında aşağıdaki adımlar izlenir:

  1. Ekleme işlemini yapılacağı aralıktan önceki düğüme dolaşıcı tarafından gidilir.
  2. Yeni düğüm oluşturularak, sonrasına, dolaşıcının sonrası atanır.
  3. Dolaşıcının sonrasına ise yeni düğüm atanır.

Yukarıdaki şekilde bu ekleme işlemi sırasıyla gösterilmiştir. İlk şekilde dolaşıcı ilgili düğüme gelmiş, ikinci şekilde yeni bir düğüm eklenmiş ve sonrasına, dolaşıcının sonrası atanmış ve son şekilde ise dolaşıcı ile gösterilen düğümün sonrasına yeni düğüm eklenmiştir.

Aynı durumu çift bağlı listeler için ele alacak olursak:

Yukarıdaki şekilde öncelikle ekleme yapılacak aralığa dolaşıcı tarafından gidilir. İkinci adımda yeni düğüm eklenir. Arından göstericiler, yukarıdaki şekilde anlatıldığı gibi sırayla atanır.

Bağlı listeden bir düğümün silinmesi

Bağlı listeden eleman silinmesi sırasında, listede silinecek olan elemandan önceki düğüme kadar dolaşıcı ile gidilir. Dolaşıcının sonrasına, sonrasının sonrası atanır. Bu sayede ilk başta dolaşıcının sonrasında olan düğüm listeden kaldırılmış ve ulaşılamaz hale gelmiş olur. Ardından bu eleman istenirse hafızadan da kaldırılır.

Bağlı listelerin nesne yönelimli programlama dillerinde pointer tipi bulunmamasından dolayı kodlanması biraz farklıdır. Bilindiği gibi C++ gibi melez (hem C hem de nesne yönelimli programlamayı destekler) diller dışında JAVA, C# gibi dillerde gösterici (pointer) bulunmaz. Bunun yerine nesne göstericisi (object referrer) bulunur. Bu değişken tipleri esas olarak bir sınıf(Class)‘dan türetilmiş bir nesneyi(object) gösterebilen değişkenlerdir. Bu değişkenlerin aslında birer göstericiden farkı yoktur.

Bağlı listenin kullanıldığı yazılar


Örnek Bağlı liste kodları:

Bu yazıyı beğendiyseniz, başkalarının da ilgisini çekebilirsiniz:


4,083 views

28 responses to “Linked List (Linkli Liste veya Bağlı Liste)”
  1. Fatih Kabakci says:

    hocam merhabalar,
    while(temp->next!=(node*)0),Arama kodunda bulunan kodun bu parcasinda,dongunun parametresi olarak bu sekil yazilmasinin,
    while(temp->next!=NULL) bu sekilde yazilmasindan islevsel olarak farki varmidir?

  2. Şadi Evren ŞEKER says:

    Null, NULL, nil veya null olarak yazılan sabit değer, her dilde tanımlı değildir. Bu yüzden kodda bulunan
    (node *) 0

    ifadesi, sayısal değer olarak 0 tam sayısını node * göstericisine tip inkılabı yapmakta (type casting) ve bu şekilde kullanmaktadır. Yukarıdaki bu tanım, her dilde (null değeri her nasıl tanımlıysa veya hiç tanımlı değilse bile) çalışması için yapılan ufak bir hiledir.

  3. Ahmet says:

    Sadi Bey circular tek yönlü bağlı listeden eleman silen kodu bu bolumde yayinlayabilirmisiniz ?

  4. kemal says:

    Çift Bağlı Dairesel listeyi visual studio 2008 de açtım ama nasıl çalıştıracam arkadaşlar bu konuda acil yardım

  5. Şadi Evren ŞEKER says:

    Kodun nasıl derlenip çalıştırılacağı aşağıdaki yazıda açıklanıyor:

    http://www.bilgisayarkavramlari.com/2008/10/06/c-ile-kodlama/

    Belki karşılaştığınız problem veya hataları yazarsanız daha fazla yardımcı olabiliriz. Kodların tamamı Dev-CPP ile test edilmiş ve çalışan kodlardır.

    başarılar

  6. Şadi Evren ŞEKER says:

    Ahmet beyin isteğine binaen yukarıya diaresel tek yönlü bağlı liste (circular singular linked list) kodu ekledim. Bu kodda insert fonksiyonu sıradan sayı eklerken, insert2 fonksiyonu sıralı bir şekilde listeye sayı ekler (büyükten küçüğe). Ayrıca del fonksiyonu da sizin istediğiniz silme işlemini yapıyor.

    umarım yardımcı olur

    başarılar

  7. gardiann says:

    merhaba; bu linked listin oncesinde bağlantılı olarak
    files of records
    fixed lenght records
    variavle lenght records file organization başlıklarıda var aslında onlarla ilgili bildiğiniz bir site turkçe olucak ama var mı lütfen!!! ??

  8. Fatih Kabakcı says:

    node *DoublyListDel(node *kutu,int data) {
    node *iter=kutu;
    while(iter->next!=NULL) {
    if(iter->next->data==data) {
    node *temp=iter->next;
    iter->next=iter->next->next;
    temp->next->prev=iter;
    free(temp);
    }
    iter=iter->next;
    }
    if(kutu->data==data) {
    node *root=kutu->next;
    root->prev=NULL;
    free(kutu);
    return root;
    }
    }
    return kutu;
    }
    Hocam Doubly listte eleman silerken yazmis oldugum bu kodda,son elemani silmek isterken sorun ile karsilasiyorum.yukaridaki while dongusunun cikisina if(iter->data==data)kosulu ekleyerek duzeltmeye calistim ama olmadi.Hatam nerdedir sizce?

  9. Şadi Evren ŞEKER says:

    doğrudur, çünkü fonksiyonunuzun içerisinde bir döngü ile iter->next’in null olması durumunu kontrol etmiş ve ancak bundan farklı birdurumda döngünün dönmesini söylemişsiniz.

    Şayet listesnizde tek eleman kaldıysa bu döngüye girmez (tek elemanın next’i null’dır). Bu durumda silme işlemi de gerçekleşmez.

    Bu tip durumlarda döngüden önce veya sonra, bu durumu kapsayan özel bir if koşulu yazmanızı tavsiye edebilirim.

    Başarılar

  10. hayal says:

    merhaba bana circular list ile ilgili bi uygulama lazım ekleme silme arama kodlarınıda içeren yardımcı olabilir misiniz?

  11. Şadi Evren ŞEKER says:

    bahsettiğiniz işlemlerin tamamını yapan kod zaten yukarıdaki yazı içerisinde bulunan bağlantıda var ve bu konuda sizden önce sorulan soruları okursanız oradaki bir ikişini isteği üzerine eklemiştim. Yine de bu kod işinizi görmüyorsa belki tam olarak istediğiniz koddan bahsederseniz yardımcı olmaya çalışabilirim.

    başarılar

  12. hayal says:

    visual studio 2008 ile çalışıyorum ben

  13. Şadi Evren ŞEKER says:

    Tekrar ediyorum yukarıdaki yazı içerisinde istediğiniz kod var. Kodlar ayrıca visual studio ile de çalışıyor.

    Kodları visual studio ile açmada sorun yaşadığınızı düşünerek, Visual Studio’da nasıl açaılacağını anlatan bir yazı yazıp yayınladım (ilgili yazıya dev-cpp-projelerinin-visual-studio-ile-acilmasi bağlığına tıklayarak ulaşabilirsiniz). Ayrıca sizin istediğiniz kodun, yani dairesel tek yönlü bağlı listenin (circular linked list) kodunu bir visual studio projesi haline getirip yukarıya bağlantısını ekliyorum.

    Umarım yardımcı olur

    başarılar

  14. Şeref Akyüz says:

    dediğiniz gibi ben c# da bu yapıyı oluşturdum, pointer kullanmadım. Açıkçası pointer la bana daha karmaşık gibi geldi…

    http://www.serefakyuz.com

  15. gül says:

    arkadasım bize hocamız c++ de cift yonlu baglantılı lısteler ıle olusturlmus ögrenci otomasyonu verdi proje olarak…otomasyonda duzenle,yenı kayıt ekleme,arama yapmave lısteleme yapma gıbı özellıkler bulunacak lıstele konutu calıstırıldıgında ogrencının vıze ve fınal notları ıle gecıp kalma durumu ıle bırlıkte adı soyadı gıbı ozellıklerı de gozterılecek…b konu da bıraz arastırma yaptım ama ısıme yarayacak bırsey bulamadım :( bana bu konu da yardımcı olursanız sevınırım

  16. Anıl Ari says:

    Çok faydalı bir yazı olmuş teşekkürler…

  17. hasan galalı says:

    Düğüm oluşturun
    2) Düğüm listesi oluşturun
    3) Listedeki düğümlerin toplamını hesaplayın , en büyüğünü ya da en küçüğünü bulun

    4) Düğüm listesinde araya düğüm eklemeniz beklenmektedir .

    merhaba hocam ben bilgisayar muh. birinci sınıf ogrencisiyim vizelerimiz dusuk oldugu için hocamız bu sorulsrı getirmemiz karsılıgındsa vizeye ekleme yapacagımızı soyledi ama gercekleyemedim yardımcı olursanız cok sevinirim

  18. Sorularınızın çözümü zaten yukarıdaki yazıda bulunan kodlarda bulunuyor. Sadece toplam bulunmuyor bunun için de listeyi bastırırken bir değişken içerisinde biriktirme (accumulate) yapmanız yeterlidir.

    Başarılar

  19. Tolga says:

    İyi akşamlar Sadi Bey. benim sorum da linked list yani bağlı listeler hakkında olucaktı. ‘ farklı dosyadan 2 farklı metin okuyup kelimelerini karşılaştırmam gerekiyor.Bunları yaparken verimli bir linked list oluşturmam gerekiyor.Bir dosyadaki farklı kelime sayısını bulmam ve aynı olan kelimeleri de saymam gerekiyor.Dosyalardan okuyup kelime kelime yazdırdm ekrana ama karşılaştırmada sorun yaşıyorum sanırım mantığını kuramadım yardımcı olabilirseniz çözmek isterim :) İyi çalışmalar

  20. Anladığım kadarıyla kelime sayısı belli olmadığı için bağlı liste kullanacaksınız. Kelimeleri okumayı başardığınıza göre en mantıklı yol, kelime okudukça bağlı listeye eklemek (ekrana bastırmak yerine bunu yapmanız yeterli).

    bu işlemi yaparken dizgi karşılaştırma (string comparison) fonksiyonlarına ihtiyacınız olacak. Bunu string.h kütüphanesinden strcmp() fonksiyonu ile çözebilirsiniz. Geriye bağlı listeyi sıralı tutmak kalıyor ki hız açısından bunu tavsiye ederim. Yani eklenen her kelime, alfabetik olarak doğru aralığa sokulmalı. Bunu yapan kod zaten yukarıda var (sıralı bağlı liste kodlarına bakabilirsiniz)

    Son olarak iki listeyi karşılaştırıp aynı olan kelimeleri saymak kalıyor ki burada da iki liste üzerinde dönen iki dolaşıcı (iterator) oluşturup adım adım ilerletmek kalıyor. Algoritma kabaca böyle anlaşılmayan bir kısım olursa ya da kodlamakta takıldığınız bir nokta, sorabilirsiniz daha detaylı bilgi verebilirim.

    Başarılar

  21. ela says:

    boyutları birbirinden farklı iki bağlı listeyi toplayıp farklı bir bağlı listeye atma işlemi nasıl yapılır yardımcı olur musunuz?

  22. Soruda açık bir iki nokta var, hangi dilde istenmiş ve toplamak ile istenen nedir? Buradaki toplamak işlemi kritik işlemdir. Şayet toplamak ile kast edilen, listelerin uç uca eklenmesi ise ve kod C dilinde yazılacaksa aşağıdaki şekildeki bir yapıyı ele alalım: (struct)

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

    Yukarıdaki yapıda verilen iki listeden ilklistenin ilk elemanını (head) tutan değişken node * l1 ve ikincisi ise node *l2 ise, ekleme işlemi aşağıdaki gibi bir fonksiyon ile yapılabilir:

    node * topla(node *l1, node* l2){
       node *iter = l1;
       while (iter->next != NULL)
           iter = iter->next;
       iter->next = l1;
       return l1;
    }
    

    algoritmada, basitçe bir iter (dolaşıcı) tanımlayıp, ilk listenin sonuna kadar gidiyoruz. Bu listenin sonuna ulaşınca ikinci listenin ilk elemanını (l2) listenin son elemanının next’ine koyuyoruz dolayısıyla l1->l2 şeklinde bir bağlantı oluşturmuş oluyoruz.

    Şayet toplamak ile kast ettiğiniz şey farklı ise bunu belirtin ona göre yazmanız gereken kodu düzenleyelim.

    Başarılar

  23. ela says:
    void topla(blisteler liste1,blisteler liste2,blisteler liste3){
              bliste gecici1 = liste1.ilk;
              bliste gecici2 = liste2.ilk;
    
             while(gecici1!=null && gecici2!=null){
                  liste3.Ekle(liste3.bilgiAl(gecici1.katsayi+gecici2.katsayi));
                  gecici1 = gecici1.sonraki;
                  gecici2 = gecici2.sonraki;
              }
    

    java dilinde yazıyorum listedeki elemanları toplamaya çalışıyorum fakat uzun olan listedeki elemanları liste3 e atmıyor bunu nasıl halledeblirim ….?

  24. Anladım, aşağıdaki şekilde deneyin:

    void topla(blisteler liste1,blisteler liste2,blisteler liste3){
              bliste gecici1 = liste1.ilk;
              bliste gecici2 = liste2.ilk;
    
             while(gecici1!=null && gecici2!=null){
                  liste3.Ekle(liste3.bilgiAl(gecici1.katsayi+gecici2.katsayi));
                  gecici1 = gecici1.sonraki;
                  gecici2 = gecici2.sonraki;
              }
             if(gecici1 != null)
                      while(gecici1 != null){
                               liste3.Ekle(gecici1.katsayi);
                      }
             if(gecici2 != null)
                      while(gecici2 != null){
                               liste3.Ekle(gecici2.katsayi);
                      }
    

    çözümünüzde listelerden birisi bitince döngü bitmiş. Burası doğru ancak listelerden birisi uzunsa bu listeye özel olarak döngünün devam etmesi gerekir. Yeni halinde liste1 erken bittiyse liste2, liste2 erken bittiyse liste1′deki elemanlar kopyalanır.

    Aslında if satırlarına gerek yok sadece while blokları da yeterli ancak anlaşılsın diye iki ihtimali yazdım. Aynı kod aşağıdaki şekilde de çalışır

    void topla(blisteler liste1,blisteler liste2,blisteler liste3){
              bliste gecici1 = liste1.ilk;
              bliste gecici2 = liste2.ilk;
    
             while(gecici1!=null && gecici2!=null){
                  liste3.Ekle(liste3.bilgiAl(gecici1.katsayi+gecici2.katsayi));
                  gecici1 = gecici1.sonraki;
                  gecici2 = gecici2.sonraki;
              }
                      while(gecici1 != null){
                               liste3.Ekle(gecici1.katsayi);
                      }
                      while(gecici2 != null){
                               liste3.Ekle(gecici2.katsayi);
                      }
    

    Başarılar

  25. deniz says:

    boyutları birbirinden farklı iki bağlı listeyi toplayıp farklı bir bağlı listeye atma işlemi nasıl yapılır yardımcı olur musunuz?
    java ile olacak
    liste1 ve liste 2 olacak karşılık lı sıradakiler toplanıp yeni oluşturulan liste3 e eklence
    bana bu konu da yardımcı olursanız sevınırım

  26. Sanırım bir önceki yorumda yazılan soruya verdiğim cevap sizin de işinizi görüyor. Şayet istediğiniz farklıysa farkını belirtmeniz durumunda yardımcı olmaya çalışayım.

    Başarılar

  27. deniz says:

    tamam sağ olun o işimi görür gibi iyi çalışmalar

  28. ela says:
    void topla(blisteler liste1,blisteler liste2,blisteler liste3){
              bliste gecici1 = liste1.ilk;
              bliste gecici2 = liste2.ilk;
    
             while(gecici1!=null && gecici2!=null){
                  liste3.Ekle(liste3.bilgiAl(gecici1.katsayi+gecici2.katsayi));
                  gecici1 = gecici1.sonraki;
                  gecici2 = gecici2.sonraki;
              }
    
                 while(gecici1!=null){
                     liste3.Ekle(liste3.bilgiAl(gecici1.katsayi));
                     gecici1 = gecici1.sonraki;
                 }
    
                 while(gecici2!=null){
                     liste3.Ekle(liste3.bilgiAl(gecici2.katsayi));
                      gecici2 = gecici2.sonraki;
                 }
          }
    

    hocam sağolun yardım ettiğiniz için birkaç düzeltmeden sonra yukarıdaki şekliyle kod çalıştı iyi geceler tekrar teşekkürler…. :)

Leave a Reply


7 - = beş

Benzer Yazılar:

Bilgisayar Kavramları üzerinde şu anda okumakta olduğunuz 'Linked List (Linkli Liste veya Bağlı Liste)' isimli yazı 03 May 2007 tarihinde, saat: 02:50 'de �adi Evren �EKER tarafından gönderilmiş, toplam4,083 defa okunmuştur.

Benzer yazıları C/C++, Programlama Dilleri, veri yapıları kategorilerinden okuyabilirsiniz. Yazar ile irtibat kurmak için email gönderebilirsiniz. Yazıya yorum yapabilir ya da yapılan yorumları RSS 2.0 ile takibe alabilirsiniz.


Category: C/C++, Programlama Dilleri, veri yapıları