System.Collections.Generic代碼閱讀筆記LinkedList SortedDictionary SortedList SortedSet

來源:互聯網
上載者:User

代碼來自ILSpy分析結果,與實際代碼可能有些微出入。手寫版http://min.us/mqjnYB

從下面可以看到,LinkedList是雙向鏈表,但是SortedList實際上使用的還是數組。

而SortedDictionary與SortedSet關係非常緊密。

----------------------------------------------------------

----------------------------------------------------------

LinkedList<T> 通過雙向鏈表這種資料結構實現。

關鍵資料成員:LinkedListNode head;

很顯然這是鏈表的頭。每個Node會有Previous以及Next這樣的property。

Find()功能通過遍曆List實現,所以是O( n )

----------------------------------------------------------

----------------------------------------------------------

Queue<T> 先進先出的隊列。

關鍵資料成員: T[] _array; 毫無疑問,是通過數組來存放資料。

_tail; _head; _size;

有頭有尾有大小,基本就是這樣。

關鍵操作Enqueue()入隊列 Dequeue()出隊列。

----------------------------------------------------------

----------------------------------------------------------

SortedDictionary<T> 索引值對字典資料類型,介面是IDictionary<TKey, TValue>。

內部關鍵資料成員TreeSet< KeyValuePair<TKey, TValue> > _set;

而TreeSet繼承了SortedSet,操作基本上都是通過類似這樣:第一個值使用Key,第二個值使用Default(TValue)
構造產生,然後調用_set的相關操作。

----------------------------------------------------------

----------------------------------------------------------

SortedList<T> 排序列表

TKey[] keys;

TKey[] values;

_size;

Add(),通過Array.BinarySearch<TKey>找到索引位置,然後進行插入操作。O(log n)。

----------------------------------------------------------

----------------------------------------------------------

另外要說一下,這裡面的比較都是使用了IComparer,這實際上使用了設計模式中的策略模式,讓使用者可以自己定製。預設情況下是使用Comparer<T>.Default.

----------------------------------------------------------

----------------------------------------------------------

SortedSet<T>

關鍵資料成員:SortedSet<T>.Node root;

插入操作為AddIfNotPresent()這個函數名字已經說明了一切。

內部構造使用的資料結構為紅/黑樹狀結構(一種自平衡二叉搜尋樹),有IsBlack和IsRed,以及Left、Right這些property。

搜尋、插入、刪除都是O(log n)。

----------------------------------------------------------

另外要注意其中的Reverse()函數,使用了yield return xxx;以及yield break;這兩種用法。

----------------------------------------------------------

----------------------------------------------------------

Stack<T>

T[] _array; 後進先出,沒啥可說的。

----------------------------------------------------------

HashSet<T>

關鍵資料成員:

int[] m_buckets;

HashSet<T>.Slot[] m_slots;

----------------------------------------------------------

Slot的定義如下:

internal struct Slot
{
  internal int hashCode;
  internal T value;
  internal int next;
}

搜尋或者是插入演算法基本上是這個路子:

----------------------------------------------------------

int num = this.InternalGetHashCode(value);
for (int i
= this.m_buckets[num % this.m_buckets.Length] - 1; i >= 0; i
= this.m_slots[i].next)
{
   //if (this.m_slots[i].hashCode ==
num && this.m_comparer.Equals(this.m_slots[i].value, value))

}

----------------------------------------------------------

這裡是搜尋,先算出一個雜湊值,然後判斷在那個桶中,拿到桶裡面第一個元素(this.m_slots[i])。

然後通過next這個成員變數來擷取下一個索引位置,然後對hash代碼以及通過comparer比較。

(圖片來自http://en.wikipedia.org/wiki/Hash_table)

----------------------------------------------------------

插入操作也差不多,在這裡面有一個this.m_freeList(一個int整數)儲存了空閑列表位置,

然後把要插入的元素放在這個列表位置,再把m_freelist設定為這個列表位置的next。

因為空白間可能不是連續的,所以我們使用的m_freelist這個位置與next未必是緊挨著的關係。

這個空閑列表的next關係維護,是由IncreaseCapacity()函數完成。其實C語言中的malloc函數也可以這樣簡單實現(當然實際中malloc肯定是複雜的多得多得多)。

----------------------------------------------------------

----------------------------------------------------------

ILSpy是個好東西,最新版本在這裡下載http://www.ilspy.net/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.