Jump to content
  • entries
    33
  • comments
    0
  • views
    1,227

İkili bağlı listeler (Doubly Linked Lists)


Doğuhan ELMA

36 views

İkili bağlı listeler (Doubly Linked Lists) veri yapılarından biridir. Bu yapıda her düğüm kendisinden önceki ve sonraki düğümlerin referanslarını tutar. Bu, verilerin iki yönde de gezinilmesine olanak tanır. İkili bağlı bir listenin her bir düğümü genellikle bir veri kısmı ve iki referans kısmı içerir. Bu referanslar, düğümün kendisinden önceki ve sonraki düğümlere işaret eder.

İkili bağlı listenin bir şeması şu şekilde olabilir:

1.pngdoubly-linked-list2.png

İkili bağlı listelerin bazı özellikleri şunlardır:

Çift Yönlü Gezinme: Her düğüm, kendisinden önceki ve sonraki düğümlere işaret ettiği için, listeyi hem ileri hem de geri yönde gezebilirsiniz.

Ekleme ve Silme: İkili bağlı listelerde ekleme ve silme işlemleri, düğüm referanslarının doğru şekilde güncellenmesiyle kolaylıkla yapılabilir. Bir düğümü silmek veya eklemek istediğinizde, sadece o düğüme komşu olan düğümlerin referanslarını güncellemeniz gerekir.

Hafıza Kullanımı: İkili bağlı listeler, her düğümde bir ek referans sakladığından, tek yönlü bağlı listelere göre daha fazla hafıza kullanır.

Başlangıç ve Son Noktada Erişim: İkili bağlı listeler, başlangıç ve son noktaya erişim sağlamak için genellikle baş ve kuyruk referansları içerir. Bu, listenin her iki ucunda da işlemleri hızlandırır.

Karmaşıklık: İkili bağlı listelerde ekleme ve silme işlemleri genellikle O(1) zaman karmaşıklığına sahip olabilir, ancak arama işlemi O(n) zaman karmaşıklığına sahip olabilir, çünkü aranan öğeyi bulmak için listeyi taramanız gerekir (burada n, listenin boyutudur).

İkili bağlı listeler, bir dizi uygulama için kullanışlıdır, özellikle de verilerin iki yönde de gezinilmesi gerektiğinde. Bununla birlikte, ekstra referansların hafıza maliyeti göz önünde bulundurulmalıdır.

Bir sentinel, bir veri yapısında işlemleri kolaylaştırmak amacıyla kullanılan özel bir düğüm veya değerdir. İkili bağlı listelerle birlikte kullanıldığında, bazı işlemlerin daha etkili bir şekilde gerçekleştirilmesine yardımcı olabilir.

Sentinel kullanmanın avantajları şunlar olabilir:

Kod Karmaşıklığının Azalması: Sentineller, bazı durumları basitleştirerek kod karmaşıklığını azaltabilir. Özellikle boş liste veya listenin sonuna ulaşıldığında özel durumları işlemek yerine, sentinel düğümleri bu durumları otomatik olarak ele alabilir.

Hızlı Ekleme ve Silme: İkili bağlı bir listede başa veya sona ekleme veya silme yaparken, sentinel kullanmak bu işlemleri hızlandırabilir. Sentinel'in bulunduğu yerlerde ekstra kontrol yapmanıza gerek kalmaz, bu da işlemlerin daha hızlı yapılmasını sağlar.

Daha Az Hata Olasılığı: Kod daha basit ve daha az durum içerdiğinde, hata yapma olasılığı genellikle azalır. Sentineller, ikili bağlı listenin başlangıcını ve sonunu işaret etmek için kullanılabileceğinden, yanlışlıkla geçersiz bir referansa erişmek veya geçersiz bir düğüm oluşturmak gibi hataların oluşma olasılığını azaltabilir.

Daha Kolay Gezinme: Bazı algoritmalar, listenin başından sonuna veya sonundan başına doğru gezinmeyi gerektirir. Sentineller, bu tür algoritmaları daha düzenli ve etkili hale getirebilir, çünkü ekstra durumları kontrol etmek zorunda kalmazsınız.

Ancak, sentinellerin de bir maliyeti olabilir. Ekstra sentinel düğümleri, hafıza kullanımını artırabilir ve bazı durumlarda kodu daha karmaşık hale getirebilir. Bununla birlikte, doğru bir şekilde kullanıldığında, sentineller ikili bağlı liste işlemlerinin verimliliğini artırabilir ve kodun okunabilirliğini ve bakımını kolaylaştırabilir.

class Node:
    def __init__(self, value, prev_node=None, next_node=None):
        self.value = value
        self.prev = prev_node
        self.next = next_node

class DoublyLinkedList:
    def __init__(self):
        self.header = Node(None)  # başlık sentinel
        self.trailer = Node(None)  # kuyruk sentinel
        self.header.next = self.trailer
        self.trailer.prev = self.header
        self.size = 0

    def append(self, value):
        new_node = Node(value)
        prev_node = self.trailer.prev
        prev_node.next = new_node
        new_node.prev = prev_node
        new_node.next = self.trailer
        self.trailer.prev = new_node
        self.size += 1

    def print_list(self):
        current = self.header.next
        while current is not self.trailer:
            print(current.value, end=' ')
            current = current.next
        print()


dll = DoublyLinkedList()
dll.append(1)
dll.append(2)
dll.append(3)
dll.print_list()  # 1 2 3

 

İkili bağlı bir liste (Doubly Linked List) kullanırken ekleme (inserting) ve silme (deleting) işlemleri, düğümlerin birbirine olan referanslarının doğru bir şekilde güncellenmesini gerektirir. İşte her iki işlemin de nasıl çalıştığına dair bir açıklama:

Ekleme (Inserting)

Bir ikili bağlı listeye bir düğüm eklemek istediğinizde, eklemek istediğiniz yere bağlı olarak birkaç adımı takip etmeniz gerekir:

Düğüm Oluşturma: Yeni bir düğüm oluşturun ve eklemek istediğiniz değeri içine koyun.

Yer Bulma: Eklemek istediğiniz yeri bulun. Bu, listenin başı, sonu veya belirli bir indeks olabilir.

Referansları Güncelleme: Yeni düğümün önceki ve sonraki referanslarını güncelleyin, böylece doğru düğümlere işaret eder. Ayrıca, yeni düğüme komşu olan düğümlerin referanslarını da güncelleyin, böylece yeni düğüme işaret ederler.

Boyutu Güncelleme: Listenin boyutunu bir artırın (eğer boyutu takip ediyorsanız).

Silme (Deleting)

Bir ikili bağlı listeden bir düğüm silmek istediğinizde, aşağıdaki adımları takip etmeniz gerekir:

Düğümü Bulma: Silmek istediğiniz düğümü bulun.

Referansları Güncelleme: Silmek istediğiniz düğümün önceki ve sonraki düğümlerinin referanslarını güncelleyin, böylece silinen düğümü atlayacak şekilde işaret ederler.

Düğümü Temizleme: İlgili düğümü bellekten silmek için referansları temizleyin (Python gibi dillerde bu, genellikle otomatik olarak gerçekleşir).

Boyutu Güncelleme: Listenin boyutunu bir azaltın (eğer boyutu takip ediyorsanız).

Örnek Kod

Aşağıda, önceki örneğe ekleme ve silme işlevleri eklenmiş bir Python kodu bulunmaktadır:

# ... (Önceki sınıflar: Node ve DoublyLinkedList'in başlangıcı)

    def insert(self, value, position):
        if position < 0 or position > self.size:
            print("Invalid position")
            return
        new_node = Node(value)
        current = self.header if position <= self.size // 2 else self.trailer
        for _ in range(position if position <= self.size // 2 else self.size - position + 1):
            current = current.next if position <= self.size // 2 else current.prev
        new_node.prev = current.prev
        new_node.next = current
        current.prev.next = new_node
        current.prev = new_node
        self.size += 1

    def delete(self, position):
        if position < 0 or position >= self.size:
            print("Invalid position")
            return
        current = self.header.next if position <= self.size // 2 else self.trailer.prev
        for _ in range(position if position <= self.size // 2 else self.size - position - 1):
            current = current.next if position <= self.size // 2 else current.prev
        current.prev.next = current.next
        current.next.prev = current.prev
        self.size -= 1

# ... (Önceki sınıfların devamı ve kullanım örnekleri)

Bu kod, belirli bir konuma bir düğüm eklemek ve belirli bir konumdaki bir düğümü silmek için iki işlev içermektedir. Her iki durumda da, düğümlerin referanslarının doğru bir şekilde güncellenmesi çok önemlidir, aksi takdirde liste bozulabilir.

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...