2013-04-17 28 views
7

Çok basit bir şey yapmaya çalışıyorum ama SortedDictionary'u anlamıyorum.SortedDictionary, C# içinde nasıl düzgün kullanılır?

Ne yapmaya çalışıyorum aşağıdadır:
I sonra şimdi bazı yüzen sayısına göre benim öğeleri sıralar Sıralanmış sözlük oluştur, bu yüzden bu

SortedDictionary<float, Node<T>> allNodes = new SortedDictionary<float, Node<T>>(); 

gibi görünen bir sözlük oluşturmak Ve ürün ekle, onları tek tek kaldırmak istiyorum (her kaldırma işlemi bir O (log (n)) karmaşıklığı en küçükten en büyüğüne olmalıdır.

Nasıl yapabilirim? Ben sadece allNodes[0] bana en küçüğü ver, ama yapmıyor

Daha fazla, sözlük yinelenen tuşları tutamaz gibi görünüyor. Yanlış veri yapısını kullanıyorum gibi hissediyorum ...
Uzaklıklarına göre sıralamak istediğiniz düğümlerim varsa (başka bir şey kullanmalıyım) başka bir şey kullanmalı mıyım (kayan nokta)?

+0

sözlük Anahtar değerlerin benzersiz olmak zorunda. Listeler yinelenen girişlere sahip olabileceğinden bunun yerine bir List > kullanmak istediğinizi düşünüyorum. Ardından, veriyi içeride olmasını istediğiniz sıraya göre işlemek için LINQ kullanın. –

+1

Her düğümün sahip olduğu bazı değerlere göre düğümlerin bir koleksiyonunu sıralamak mı istiyorsunuz yoksa bir "SortedDictionary" kullanmak için gereken belirli bir neden var mı? ? Eğer eskiyse, koleksiyonun ne zaman başladığına bakılmaksızın LINQ 'OrderBy'yi kullanmanız yeterlidir. – Servy

+0

O (Log (n)) içine eklemek ve kaldırmak istiyorum, işimin çoğunu eklemek ve kaldırmak ... O (N) içinde hangi liste var. ve sorunuza göre: sıralama her düğümde bir değere dayanır. – OopsUser

cevap

14

allNodes[0] size sözlükte ilk öğeyi vermeyecektir - birile size öğeyi verecektir anahtarının anahtarının 0.

İlk öğeyi istiyorsanız, allNodes.Values.First() deneyin. Ya tek tek öğeleri kaldırmak allNodes.Keys.First()

için ilk anahtar kullanımını bulmak için, bir kopya üzerinde döngü Keys koleksiyonun ve Ekinizi cevaplamak için allNodes.Remove(key);

foreach (var key in allNodes.Keys.ToList()) 
{ 
    allNodes.Remove(key); 
} 

diyoruz senin soru, evet SortedDictionary (bu konu için Dictionary herhangi bir lezzeti) yinelenen anahtarları işlemez - eğer mevcut bir anahtarla bir öğe eklemeye çalışırsanız üzerine yazacaktır değerli değer.

Sen kullanabileceği bir SortedDictionary<float, List<Node<T>>> ama o zaman her liste başlatmak gerek yerine sadece Her şey mümkündür, vb bir öğe ekleme ve hala en hızlı yapı olabilir, koleksiyonları öğeler karşı ayıklanması karmaşıklığını var ekler ve alır, ancak biraz karmaşıklık ekler.

0

Dictionary<TKey, TValue>'un benzersiz anahtarları olması gerekir, bunun yerine List<Node<T>> kullanırdım. Örneğin, Node<T> sınıf bir Value özelliği

class Node<T> 
{ 
    float Value { get; set; } 
    // other properties 
} 

sahiptir ve bu özelliğiyle sıralamak istiyorsanız, LINQ kullanmak:

var list = new List<Node<T>>(); 

// populate list 

var smallest = list.OrderBy(n => n.Value).FirstOrDefault(); 

sadece listede attı yineleme, tek tek düğümleri kaldırmak için :

while (list.Count > 0) 
{ 
    list.RemoveAt(0); 
} 
1

Evet, karmaşıklık konusunda haklısınız.

SortedDictionary10'da tüm tuşlar sıralanmıştır.Eğer en küçüğünden en büyüğüne yineleme yapmak istiyorsanız, foreach yeterli olacaktır: Eğer öğeleri kaldırmak istediğinizi yazdığı

foreach(KeyValuePair<float, Node<T>> kvp in allNodes) 
{ 
    // Do Something... 
} 

. foreach ile yineleme sırasında koleksiyonlardan kaldırılması yasaktır, bu nedenle öncelikle bunun bir kopyasını oluşturun.

DÜZENLEME: Eğer tuşları çoğaltılamaz varsa

Evet, SortedDictionary kullanamazsınız. Node<T> ve float ile yapısal Düğümü oluşturun, ardından bir karşılaştırıcısı yazmak: o zaman

public class NodeComparer : IComparer<Node> 
{ 
    public int Compare(Node n1, Node n2) 
    { 
     return n2.dist.CompareTo(n1.dist); 
    } 
} 

Ve sıralama basit List<Node> allNodes her şeyi koymak ve:

allNodes.Sort(new NodeComparer()); 
İlgili konular