Menu
Coddy logo textTech

Çift Yönlü Bağlı Liste

Son güncelleme

Çift yönlü bağlı liste, her düğümün iki işaretçi tuttuğu bir bağlı listedir: next (sonraki düğüme) ve prev (önceki düğüme). Bu ek geriye dönük bağlantı, her iki yönde de gezinmenizi ve zaten bir referansınız olan bir düğümü O(1) sürede silmenizi sağlar; çünkü baştan yürümek yerine önceki düğüme doğrudan ulaşabilirsiniz. Düğümlerin her iki yönde bağlanıp yeniden bağlanmasını izlemek için yukarıdaki oynat düğmesine basın.

Bunun maliyeti, düğüm başına fazladan bir işaretçi ve daha fazla defter tutmadır: her ekleme ve silme, komşulardaki hem next hem de prev alanını güncellemelidir. Bu, her iki uçtan hızlı silmenin önemli olduğu birçok deque ve LRU önbelleğinin arkasındaki yapıdır.

Zaman karmaşıklığı

İşlemKarmaşıklıkNotlar
Başa/sona eklemeO(1)Baş ve son işaretçileriyle
Bilinen bir düğümü silmeO(1)prev'e doğrudan ulaşılır, yürüme yok
AramaO(n)Yine doğrusal tarama
İndeksle erişimO(n)Rastgele erişim yok

Tek yönlü ve çift yönlü bağlı liste

YönTek yönlüÇift yönlü
Düğüm başına işaretçi1 (next)2 (next + prev)
Geriye gezinmeHayırEvet
Bilinen bir düğümü silmeO(n) (prev'i bul)O(1)
Bellek ek yüküDaha düşükDaha yüksek

Çözümlü örnek

Sona ekleyerek [10, 20, 30] oluşturma, ardından 20 düğümünü silme:

AdımYapıEylem
BaşlangıçnullBoş liste: head ve tail ikisi de null
10 ekle10İlk düğüm; head ve tail ona işaret eder, prev = next = null
20 ekle10 <-> 2010.next = 20 ve 20.prev = 10 ayarlanır; tail = 20
30 ekle10 <-> 20 <-> 3020.next = 30 ve 30.prev = 20 ayarlanır; tail = 30
20'yi sil10 <-> 3020.prev ve 20.next kullanılarak: 10.next = 30 ve 30.prev = 10 O(1) sürede ayarlanır

Çift yönlü bağlı liste ne zaman kullanılır

Şu durumda kullanŞu durumda kaçın
Her iki yönde gezinmen veya bağlaman gerekirYalnızca ileri gidersin: tek yönlü liste daha hafiftir
Zaten referansını tuttuğun rastgele düğümleri silersin (O(1))Genellikle konuma göre indekslersin: O(1) erişim için dizi kullan
Bir deque, LRU önbelleği veya geri alma geçmişi uygularsınBellek dardır: ek prev işaretçisi bağlantı ek yükünü ikiye katlar
Eklemeler ve çıkarmalar sık sık her iki uçta olurVeri küçüktür ve nadiren değişir: dizi kopyalamak daha ucuzdur

Doubly Linked List kodu

Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir Doubly Linked List uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.

Python ile Doubly Linked List kodu

Python
1class Node:2    def __init__(self, value):3        self.value = value4        self.prev = None5        self.next = None6
7
8class DoublyLinkedList:9    def __init__(self):10        self.head = None11        self.tail = None12
13    def append(self, value):14        node = Node(value)15        if self.tail is None:16            self.head = self.tail = node17            return18        # Wire both directions: old tail <-> new node19        node.prev = self.tail20        self.tail.next = node21        self.tail = node22
23    def prepend(self, value):24        node = Node(value)25        if self.head is None:26            self.head = self.tail = node27            return28        node.next = self.head29        self.head.prev = node30        self.head = node31
32    def forward(self):33        values, current = [], self.head34        while current:35            values.append(current.value)36            current = current.next37        return values38
39    def backward(self):40        values, current = [], self.tail41        while current:42            values.append(current.value)43            current = current.prev44        return values45
46
47lst = DoublyLinkedList()48for value in [2, 3, 4]:49    lst.append(value)50lst.prepend(1)51
52print("Forward: ", lst.forward())53print("Backward:", lst.backward())
Bu kodu Python Playground'da çalıştır

Çift Yönlü Bağlı Liste SSS

Tek yönlü ve çift yönlü bağlı liste arasındaki fark nedir?
Tek yönlü bağlı listede düğüm başına bir işaretçi vardır (next), bu yüzden yalnızca ileri gidebilirsiniz. Çift yönlü bağlı liste bir prev işaretçisi ekler; bu, geriye gezinmeyi ve referansını tuttuğunuz bir düğümü O(1) sürede silmeyi sağlar; bunun bedeli düğüm başına ek bir işaretçi ve her değişiklikte iki bağlantıyı güncellemektir.
Çift yönlü bağlı liste ek belleğe ne zaman değer?
Geriye gezinmeye ya da zaten referans verdiğiniz rastgele düğümlerin O(1) silinmesine ihtiyaç duyduğunuzda; klasik örnekler, girdilerin her iki uçtan sık sık taşındığı ve atıldığı deque'ler (çift uçlu kuyruklar) ve LRU önbellekleridir.
Çift yönlü bağlı liste neden bir düğümü O(1) sürede silebilir?
Bir düğümü kaldırmak için öncülünü ardılına bağlamanız gerekir. Tek yönlü bağlı listede öncülü bulmak için baştan yürümeniz gerekir (O(n)); çift yönlü bağlı listede düğümün prev işaretçisi öncülü doğrudan verir, bu yüzden yeniden bağlama O(1) olur.
Çift yönlü bağlı liste ve dizi: hangisini kullanmalıyım?
İndeksle O(1) erişime ve önbellek dostu yinelemeye ihtiyaç duyduğunuzda ve eklemeler çoğunlukla sonda olduğunda dizi kullanın. Bir düğüm referansıyla ortada veya her iki uçta sık sık ekleyip çıkarıyorsanız çift yönlü bağlı liste kullanın; çünkü bu, dizinin O(n) kaydırmasına karşı O(1)'dir. Diziler bellek ve yerellikte kazanır; liste yapısal düzenlemelerde kazanır.
Çift yönlü bağlı listede nöbetçi (sentinel) düğüm nedir?
Nöbetçi (veya kukla) düğüm, listenin hiçbir zaman gerçekten boş olmaması için başın önünde ve/veya sonun ardında duran bir yer tutucudur. head, tail ve sınır ekleme/silmeleri için null kontrollerini ortadan kaldırarak her işlemin aynı yeniden bağlama kod yolunu izlemesini sağlar. Birçok üretim LRU önbellek uygulaması, uçları özel durum olarak ele almamak için iki nöbetçi kullanır.
Çift yönlü bağlı listeden silerken en yaygın hata nedir?
İlk veya son düğümü silerken head ya da tail'i güncellemeyi unutmak; bu, serbest bırakılmış bir düğüme sarkan bir işaretçi bırakır. Komşuları yeniden bağlamadan önce node.prev'in null olup olmadığını (head'i güncelle) veya node.next'in null olup olmadığını (tail'i güncelle) her zaman kontrol edin.
Coddy programming languages illustration

Coddy ile algoritmalarda ustalaş

BAŞLA