Dictionary
Dictionary
1. 實(shí)現(xiàn)
查閱 MSDN 得到如下資料:
Dictionary
檢索速度取決于為TKey指定的類型的哈希算法的質(zhì)量。
可見,Dictionary
SortedDictionary
SortedList
SortedDictionary
如果使用排序數(shù)據(jù)一次性填充列表,則SortedList
每個(gè)鍵/值對(duì)都可以作為KeyValuePair
只要鍵用作SortedDictionary
SortedDictionary
C#語言的foreach語句需要集合中每個(gè)元素的類型。由于SortedDictionary
可見,SortedDictionary
1. foreach
2. Object.GetEnumerator
小實(shí)驗(yàn):
CODE:
SortedDictionary
TestObject.Add(7, 2);
TestObject.Add(0, 1);
TestObject.Add(5, 3);
TestObject.Add(1, 1);
TestObject.Add(4, 4);
foreach (KeyValuePair
{
Console.WriteLine(kvp.Key);
}
得到的順序是0,1,4,5,7(SortedList
但是如果把SortedDictionary
另一種遍歷方法:
CODE:
SortedDictionary
while (sde.MoveNext())
{
Console.WriteLine(sde.Current.Key);
}
SortedDictionary
QUOTE:
二叉樹的插入操作怎么是 O(n)?
網(wǎng)上有一種說法, 就是SortedList
CODE:
Random ra = new Random();
SortedList
for (int i = 1; i <= 1000000; i++)
{
TestObject.Add(i, ra.Next());
}
其中,ra.Next()用來生成隨機(jī)數(shù)。
上述代碼執(zhí)行速度相當(dāng)快,因?yàn)椴迦氲臄?shù)據(jù)的Key值是有序的。
如果把i換成1000000-i,則速度立刻慢得慘不忍睹。
同樣的情況出現(xiàn)在把i替換成隨機(jī)數(shù)。在一段時(shí)間的等待后出錯(cuò),因?yàn)镵ey值不能重復(fù)。
這樣說來,SortedList
SortedList
方法(使用屬性)是object.Key[k]和object.Value[k)。
這更加印證了網(wǎng)上的說法.
我認(rèn)為SortedList沒什么用 - 除非是對(duì)基本有序的數(shù)據(jù),或者對(duì)內(nèi)存非常吝嗇。如果僅僅需要在BST上加上查找排名為k的節(jié)點(diǎn)的功能,可以使用一個(gè)經(jīng)典算法:在每個(gè)節(jié)點(diǎn)上加上一個(gè)leftsize,儲(chǔ)存它左子樹的大小。
2. 功能
這三個(gè)類的功能上面都講得差不多了。因?yàn)閷?shí)現(xiàn)就決定了功能。這里小結(jié)一下。
Dictionary
Add,Clear,ContainsKey,ContainsValue,Count(屬性),Enumerator(無序),Item(屬性), Remove
SortedDictionary
Enumerator為有序 - 對(duì)應(yīng)BST的中序遍歷。
SortedList
Capacity(屬性) - 畢竟人家是數(shù)組
IndexOfKey,IndexOfValue(返回Value對(duì)應(yīng)Key的排名而不是 Value 的排名)
Keys[k],Values[k] - 返回按照Key排序的數(shù)組的第k個(gè)元素
3. 速度
實(shí)踐出真知 - 某名人。
理論和實(shí)踐不符就是錯(cuò)的 - Thity。
我們的測試程序:
CODE:
static class DictionarySpeedTest
{
static Random RandomGenerator = new Random();
static List
static Dictionary
public struct Key_N_Data
{
public long Key;
public long Data;
}
const int ITEM_COUNT = 1000000;
const int TEST_COUNT = 500000;
static long LastTick;
public static void TimerStart(string Text)
{
Console.Write(Text);
LastTick = DateTime.Now.Ticks;
}
public static void TimerEnd()
{
long t = DateTime.Now.Ticks - LastTick;
Console.WriteLine(((t) / 10000).ToString() + " ms");
}
public static void Main()
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Console.WriteLine(TestObject.GetType().ToString());
TimerStart("Generating data... ");
for (int i = 1; i <= ITEM_COUNT; i++)
{
Key_N_Data ThisKeyData = default(Key_N_Data);
ThisKeyData.Key = ((long)RandomGenerator.Next() << 31) | RandomGenerator.Next();
ThisKeyData.Data = ((long)RandomGenerator.Next() << 31) | RandomGenerator.Next();
ArrayListData.Add(ThisKeyData);
}
TimerEnd();
TimerStart("Test 1: add data test... ");
foreach (Key_N_Data Item in ArrayListData)
{
TestObject.Add(Item.Key, Item.Data);
}
TimerEnd();
TimerStart("Test 2: find data test... ");
for (int i = 1; i <= TEST_COUNT; i++)
{
{
if (TestObject[ArrayListData[RandomGenerator.Next(0, ITEM_COUNT)].Key] != ArrayListData[RandomGenerator.Next(0, ITEM_COUNT)].Data)
Console.WriteLine("Error!");
}
}
TimerEnd();
TimerStart("Test 3: remove data test...");
for (int i = 1; i <= TEST_COUNT; i++)
{
TestObject.Remove(ArrayListData[RandomGenerator.Next(0, ITEM_COUNT)].Key);
}
TimerEnd();
Console.Read();
}
}
通過更改TestObject的類型,我們可以很方便地比較這三個(gè)類的速度。測試結(jié)果:
ADD FIND REMOVE
Dictionary
SortedDictionary
SortedList
我們把ITEM_COUNT和TEST_COUNT都減小10倍:
ADD FIND REMOVE
Dictionary
SortedDictionary
SortedList
SortedList
4. 小結(jié)
如果只是當(dāng)作索引使用,請(qǐng)用Dictionary
如果需要查找最小的幾個(gè)元素,或者需要按順序遍歷元素,就用SortedDictionary
如果輸入/刪除的元素是基本增序的,或者訪問次數(shù)遠(yuǎn)多于修改次數(shù),或者需要訪問第k大的元素,或者對(duì)內(nèi)存吝嗇得BT的情況,用SortedList
PS: 微軟似乎也很吝嗇,SortedDictionary
CODE:
class MyComparer : Comparer
{
public override int Compare(long x, long y)
{
return Comparer
}
}
使用:
SortedList
現(xiàn)在我們可以來進(jìn)行一下剛開始的時(shí)候提到的Dictionary
結(jié)果:
ADD FIND REMOVE
Dictionary(Of Long, Long) 271ms 203ms 187ms
Dictionary(Of Object, Object) 468ms 312ms 234ms
Hashtable 859ms 390ms 218ms
結(jié)論: 最好用Dictionary代替Hashtable。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。