中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行C#中Dictionary的內部實現分析

發布時間:2021-11-24 14:02:55 來源:億速云 閱讀:110 作者:柒染 欄目:編程語言

本篇文章為大家展示了如何進行C#中Dictionary的內部實現分析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

了解Dictionary的開發人員都了解,和List相比,字典添加會慢,但是查找會比較快,那么Dictionary是如何實現的呢?

Dictionary的構造

下面的代碼我看看Dictionary在構造時都做了什么:

private void Initialize(int capacity)
        {
            int prime = HashHelpers.GetPrime(capacity);
            this.buckets = new int[prime];
            for (int i = 0; i < this.buckets.Length; i++)
            {
                this.buckets[i] = -1;
            }
            this.entries = new Entry<TKey, TValue>[prime];
            this.freeList = -1;
        }

我們看到,Dictionary在構造的時候做了以下幾件事:

  1. 初始化一個this.buckets = new int[prime]

  2. 初始化一個this.entries = new Entry<TKey, TValue>[prime]

  3. Bucket和entries的容量都為大于字典容量的一個最小的質數

其中this.buckets主要用來進行Hash碰撞,this.entries用來存儲字典的內容,并且標識下一個元素的位置。

我們以Dictionary<int,string> 為例,來展示一下Dictionary如何添加元素:

首先,我們構造一個:

Dictionary<int, string> test = new Dictionary<int, string>(6);

初始化后:

如何進行C#中Dictionary的內部實現分析

添加元素時,集合內部Bucket和entries的變化

Test.Add(4,”4&Prime;)后:

根據Hash算法: 4.GetHashCode()%7= 4,因此碰撞到buckets中下標為4的槽上,此時由于Count為0,因此元素放在Entries中第0個元素上,添加后Count變為1

如何進行C#中Dictionary的內部實現分析

Test.Add(11,”11&Prime;)

根據Hash算法  11.GetHashCode()%7=4,因此再次碰撞到Buckets中下標為4的槽上,由于此槽上的值已經不為-1,此時Count=1,因此把這 個新加的元素放到entries中下標為1的數組中,并且讓Buckets槽指向下標為1的entries中,下標為1的entry之下下標為0的 entries。

如何進行C#中Dictionary的內部實現分析

Test.Add(18,”18&Prime;)

我們添加18,讓HashCode再次碰撞到Buckets中下標為4的槽上,這個時候新元素添加到count+1的位置,并且Bucket槽指向 新元素,新元素的Next指向Entries中下標為1的元素。此時你會發現所有hashcode相同的元素都形成了一個鏈表,如果元素碰撞次數越多,鏈 表越長。所花費的時間也相對較多。

如何進行C#中Dictionary的內部實現分析

Test.Add(19,”19&Prime;)

再次添加元素19,此時Hash碰撞到另外一個槽上,但是元素仍然添加到count+1的位置。

如何進行C#中Dictionary的內部實現分析

刪除元素時集合內部的變化

Test.Remove(4)

我們刪除元素時,通過一次碰撞,并且沿著鏈表尋找3次,找到key為4的元素所在的位置,刪除當前元素。并且把FreeList的位置指向當前刪除元素的位置,FreeCount置為1

如何進行C#中Dictionary的內部實現分析

Test.Remove(18)

刪除Key為18的元素,仍然通過一次碰撞,并且沿著鏈表尋找2次,找到當前元素,刪除當前元素,并且讓FreeList指向當前元素,當前元素的Next指向上一個FreeList元素。

此時你會發現FreeList指向了一個鏈表,鏈表里面不包含任何元素,FreeCount表示不包含元素的鏈表的長度。

如何進行C#中Dictionary的內部實現分析

Test.Add(20,”20&Prime;)

再添加一個元素,此時由于FreeList鏈表不為空,因此字典會優先添加到FreeList鏈表所指向的位置,添加后FreeCount減1,FreeList鏈表長度變為1

如何進行C#中Dictionary的內部實現分析

通過以上試驗,我們可以發現Dictionary在添加,刪除元素按照如下方法進行:

  1. 通過Hash算法來碰撞到指定的Bucket上,碰撞到同一個Bucket槽上所有數據形成一個單鏈表

  2. 默認情況Entries槽中的數據按照添加順序排列

  3. 刪除的數據會形成一個FreeList的鏈表,添加數據的時候,優先向FreeList鏈表中添加數據,FreeList為空則按照count依次排列

  4. 字典查詢及其的效率取決于碰撞的次數,這也解釋了為什么Dictionary的查找會很快。

上述內容就是如何進行C#中Dictionary的內部實現分析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

基隆市| 黔江区| 武山县| 大姚县| 宕昌县| 广西| 阳春市| 铜陵市| 滕州市| 浮山县| 砚山县| 禹州市| 巴青县| 巴彦淖尔市| 民勤县| 射阳县| 虞城县| 龙州县| 勐海县| 抚顺县| 龙岩市| 射阳县| 奉贤区| 平度市| 兰考县| 富锦市| 本溪市| 安国市| 九龙城区| 稷山县| 库尔勒市| 红安县| 承德县| 宽城| 共和县| 儋州市| 虞城县| 嘉义市| 沾化县| 正宁县| 榆树市|