Dizi yerine bağlantılı liste kullanmak için somut kurallar nelerdir?


18

Bağlantılı bir liste, öğelerin ucuz bir şekilde eklenmesini ve silinmesini istediğinizde ve öğelerin bellekte yan yana olmaması önemli olmadığında kullanılabilir.

Bu çok soyut ve neden bir dizi yerine bağlantılı listenin kullanılması gerektiğine dair somut bir açıklama istiyorum. Programlama konusunda çok tecrübeli değilim, bu yüzden çok fazla gerçek dünya deneyimim yok.


3
Dürüst olmak gerekirse, bir şeyler yazma ve daha sonra veri yapılarını değiştirmenin kodunuz üzerindeki etkisini görene kadar örneklerin sizin için çok şey ifade edeceğini sanmıyorum. İlgilendiğiniz bir şey yazmayı deneyin ve hangi veri yapılarının ve kaplarının en uygun olduğunu bulun veya mevcut bazı kodlara bakın ve her kapsayıcıların neden seçildiğini ve bunun nasıl bir etkisi olacağını düşünün.
Yararsız

Veri yapısı seçiminin değiş tokuşlarını ve yan etkilerini (deneyimsiz) OP'ye burada makul olandan çok daha uzun biçimli bir çalışma örneği olmadan iletmenin yararlı olduğunu düşünmüyorum. Cevaplar olarak verilen örnekler gayet iyi ve soruyu sorulduğu gibi cevaplıyor, ama (okuduğum şey) gerçek anlayış için ima edilen bir talep değil.
Yararsız

Yanıtlar:


37

Örnek ve benzetme arasında kısmen bir şey var. Yapmanız gereken bazı işler var, bu yüzden bir parça kağıt alıp yazıyorsunuz:

  • banka
  • bakkaliye
  • kuru temizleme

Sonra da pul satın almanız gerektiğini hatırlarsınız. Şehrinizin coğrafyası nedeniyle, bunu bankadan sonra yapmanız gerekir. Tüm listenizi yeni bir kağıda kopyalayabilirsiniz:

  • banka
  • pullar
  • bakkaliye
  • kuru temizleme

ya da sahip olduğunuz kişiyi karalayabilirsiniz:

  • bankası ....... STAMPS
  • bakkaliye
  • kuru temizleme

Diğer işleri düşündüğünüz gibi, bunları listenin altına yazabilirsiniz, ancak okları kendilerine hangi sırayla yapacağınızı hatırlatır. Bu bağlantılı bir listedir. Her eklediğinizde listenin tamamını kopyalamaktan daha hızlı ve kolaydır.

Sonra bankadayken cep telefonunuz çalıyor "hey, pulları aldım, daha fazla almayın". STAMPS'ı listeden geçiyorsunuz, içinde STAMPS olmadan tamamen yeni bir tane yazmıyorsunuz.

Artık kodda bir iş listesi listesi uygulayabilirsiniz (belki de işlerinizi coğrafi konumunuza göre sıralayan bir uygulama) ve kodda bunun için bağlantılı bir liste kullanmanız için makul bir şans var. Çok sayıda öğe eklemek ve kaldırmak, sipariş vermek istiyorsunuz, ancak her ekleme veya silme işleminden sonra listenin tamamını yeniden kopyalamak istemiyorsunuz.



@Dennis evet, biliyorum, hareket semantiği sayesinde. Ancak bu tüm diller için geçerli değildir, bu yüzden örnek geçerlidir.
Kate Gregory

1
@KateGregory yeterince adil, ancak "temel" veri yapılarının genellikle okulda (veya başka yerlerde) öğrendiğimiz serin veri yapılarından daha iyi olduğunu belirtmek hala iyidir. Yeni mezunların LL'leri her yerde kullanmasını istemiyorum çünkü teorik olarak uygun olsa da muhtemelen gerçekçi bir şekilde kötü bir seçim. Doğru veri yapısını kullanmak önemlidir ve bazen insanlar bunu aşırı karmaşık hale getirir. Biraz ilgili veri yapıları üzerine Jonathan Blow ("Braid" in yaratıcısı) bu konuşma .
Dennis

1
@Ray: Bağlantılı bir liste, 4 öğenin sırasına göre beklerseniz bir ağaç yapısından daha iyi performans gösterebilir ve karşılaştırmalar nispeten ucuzdur. Kesinti durumun tam olarak nerede olduğunu tam olarak bilmiyorum. Ayrıca, bir ağaç yapısı verilerinizin sıralanabilmesini gerektirir, oysa bir liste yapısı ekleme sırasını (veya herhangi bir rasgele sırayı) korumanıza izin verir.
David Stone

2
Bu benzetmenin çok doğru olduğunu düşünmüyorum. İnsanlar olarak (en azından böyle kısa bir liste için) O (1) 'de bir element bulabiliriz. Ancak, bağlantılı bir listede rastgele bir ekleme yapmak istiyorsanız, ortalama olarak öğelerin yarısını geçmeniz gerekir; bu, yalnızca eklemek istediğiniz konumu bulmak için size O (n) mal olur. Gerçek kesici uç daha sonra sadece O (1) maliyetlidir, ancak bir dizi ile maliyetiniz de sadece “O” (n) olur. Bunun nedeni sadece hareket semantiğinden değil algoritmiktir. Bununla birlikte, big-O tarafından gizlenen sabit faktör, bitişik olmayan bellek erişimi nedeniyle sevilen liste için çok daha büyüktür.
5gon12eder

18
  • Karma çarpışmalarını çözmek için zincirleme kullanan karma tablolarda, genellikle bu gruptaki öğeler için grup başına bir bağlantılı liste bulunur.
  • Basit bellek ayırıcıları , kullanılmayan bellek bölgelerinin ücretsiz bir listesini , temel olarak boş belleğin içindeki liste işaretçisi olan bağlantılı bir listeyi kullanır
  • Bir de FAT dosya sistemi , büyük bir dosyanın meta FAT girişlerinin bağlantılı liste olarak düzenlenmiştir.

12

C dili "çağrı yığını" x86 (ve diğer çoğu) ikili API'larında bağlantılı bir liste olarak uygulanır .

Yani, C-dil prosedürü çağrısı bir ilk-giriş, son-çıkış disiplini takip eder. İşlev çağrılarının (muhtemelen özyinelemeli) yürütülmesinin sonucu "çağrı yığını", hatta bazen sadece "yığın" olarak adlandırılır.

CALLX86 komut "çağrı yığını" kullanarak bir bağlantılı liste implmenting biter. Bir CALLkullanıcı,% VAP kayıt içeriğini, bilginin adresini iter sonraCALL üzerine yığın bellek. Çağrılan işlev prolog, çağrı işlevindeki en düşük yerel değişkenler olan% EBP kaydının içeriğini yığın belleğine iletir. Ardından çağrılan fonksiyon prolog'u% EBP'yi geçerli fonksiyonun yığın tabanına ayarlar.

Bu,% EBP'nin, çağıran işlevin% EBP değerinin adresini tutan bir bellek konumuna işaretçi olduğu anlamına gelir. Bu, kısmen donanımda uygulanan bağlantılı bir listeden başka bir şey değildir CALL.

Bunun ne kadar iyi olduğu konusunda, x86 CPU'ların işlev çağrılarını, özellikle işlevin kendi bağımsız değişken kopyasına sahip olduğu işlev çağrılarını ve işleve yerel değişkenleri nasıl uyguladığı budur. Her işlev çağrısı, CPU'nun çağrılan fonksiyonda veya çağrı fonksiyonunda herhangi bir parazit olmadan kaldığı yerden almasını sağlayan "çağrı yığını" ile ilgili bazı bilgileri iter.


3

Bağlı bir liste, bir mesaj kuyruğu uygulamak için kullanılabilir.

İleti kuyruğu, sonraki işlemler için olaylar hakkında bilgi depoladığımız bir yapıdır. Örneğin, kullanıcı bir tuşa bastığında veya fareyi hareket ettirdiğinde, bu bir olaydır. Bir uygulama, olayın gerçekleştiği anda meşgul olabilir, bu nedenle olayın gerçekleştiği anda tam olarak işlenmesi beklenemez. Böylece, olay bir mesaj kuyruğuna yerleştirilir (hangi tuşa basıldığı veya farenin nereye taşındığı hakkında bilgi) ve uygulamanın biraz zaman ayırması durumunda, mesaj kuyruğunu kontrol eder, olayları ondan alır ve işler onlar. (Bu milisaniye içinde bir zaman dilimi içinde olur, bu yüzden farkedilemez.)

Az önce açıkladığım kullanım senaryosundan, mesaj kuyruğunda depolanan olaylara rastgele erişime sahip olmamayı umursamayacağımız açıktır; yalnızca iletileri depolayabilmeyi ve geri alabilmeyi önemsiyoruz. Bu nedenle, optimum ekleme / çıkarma süresi sağlayan bağlantılı bir liste kullanmak mantıklıdır.

(Lütfen bir mesaj kuyruğunun dairesel bir dizi listesi kullanılarak uygulanmasının muhtemel olduğunu veya daha olası olduğunu veya neredeyse muhtemel olduğunu belirtmeyin; bu teknik bir ayrıntıdır ve bir sınırlaması vardır: yalnızca depolayabilirsiniz içinde sınırlı sayıda mesaj var.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.