前言
前面幾篇文章講了泛型、講了數(shù)組,都有提到集合,這一節(jié)重點對集合進行詳細解說。本文主要使用各種集合類型。以至于評估其性能,針對不同的場景選擇不同的集合使用。
集合分類詳解
一、列表
列表的創(chuàng)建
var intList=new List<int>();
?
創(chuàng)建一個容量為10 的集合
List<int> intList=new List<int>(10);
?
列表初始值設(shè)定項
?
var intList = new List<int>() { 1,2};
?
添加元素(通過使用Add方法進行元素添加)
var intList=new List<int>(); inList.Add(1); var intList = new List<int>();
intList.AddRange(new List<int>(){ 1,2,3});
?
插入元素(使用insert方法插入元素)
var intList = new List<int>(); intList.Insert(3, 3); var intList = new List<int
>(); intList.InsertRange(3, new List<int>() { 1,2,3});
?
訪問元素(通過下表去實現(xiàn)訪問或者循環(huán)遍歷)
var intList = new List<int>(); intList.AddRange( new List<int>() { 1,2,3}); var
answer = intList[2]; foreach (var item in intList) { Console.WriteLine(item); }
?
刪除元素(通過RemoveAt指定刪除某一位置的值)
var intList = new List<int>(); intList.AddRange( new List<int>() { 1,2,3,4});
intList.RemoveAt(3);
?
搜索(通過IndexOf訪問指定位置的值,可以使用的方法IndexOf()、LastIndexOf()、FindLastIndex()、Find()、
FindLast())
var intList = new List<int>(); intList.AddRange( new List<int>() { 1,2,3,4});
int indenx = intList.IndexOf(3);
?
二、隊列
隊列是其元素以先進先出(FirstIn,F(xiàn)irstOut,F(xiàn)IFO)
的方式來處理的集合,先放入隊列中的元素會先讀取。隊列的例子比比皆是。排隊買票,食堂排隊打飯,先到先買,先到先打飯。
?
?
隊列使用System.Collections.Generic命名空間中的泛型類Queue<T>來實現(xiàn)的。這個類型類似于List<T>。隊列類使用
Enqueue()方法在隊列的一段插入元素,使用Dequeue()方法在另一端讀取元素并刪除。
?
Queue<string> qa = new Queue<string>(); qa.Enqueue("第一個進"); qa.Dequeue();
?
其中使用Count()返回隊列中的元素總數(shù),使用Peek()方法從隊列頭部讀取一個元素,但不刪除它。使用TrimExcess()方法重新設(shè)置隊列的容量,
Dequeue()雖然刪除了元素,但不會重新設(shè)置容量。要從隊列頭部去除空元素,應(yīng)使用TrimExcess()方法
三、棧
棧是與隊列非常相似的另一個容器,知識使用不同的方法訪問棧,而且棧的元素屬于最后添加的元素最先讀取也就是后進先出(LastIn,FirstOut,LIFO
)。
?
?
與Queue<T>類似,棧使用Stack<T>來實現(xiàn),其中Push()在棧中添加元素,用Pop()方法獲取最近添加的元素。
Stack<string> qa = new Stack<string>(); qa.Push("第一個進"); qa.Pop();
?
其中其他方法與Queue<T>類似,使用Count()返回隊列中的元素總數(shù),使用Peek()方法從隊列頭部讀取一個元素,但不刪除它。使用
Contains()確定某個元素是否存在于棧中,存在則返回True
?
四、有序列表
如果需要基于鍵對所需的集合進行排序,就可以使用SortedList<TKey,TValue>
類。這個類按照鍵給的元素排序,這個集合中的值和鍵都可以使用任意類型。
下面先創(chuàng)建一個空列表,然后通過Add()方法進行添加元素。然后輸出結(jié)果。我們看下圖可以發(fā)現(xiàn)自動幫我們已經(jīng)排序好了然后輸出的。
static void Main(string[] args) { var test = new SortedList<string, string>();
test.Add("First","Code1"); test.Add("Two", "Code2"); test.Add("A", "Code3");
foreach (var item in test) { Console.WriteLine(item.Key+":"+ item.Value); } }
?
?
五、字典
字典表示一種復(fù)雜的數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)允許按照某個鍵來訪問元素。字典也稱為映射或散列表。
字典的主要特性是能根據(jù)鍵快速查找值。也可以自由添加和刪除元素,這有點像List<T>,但沒有在內(nèi)存中移動后續(xù)元素的性能開銷。
字典的初始化:
var dict = new Dictionary<int, string>() { {1,"第一個" },{2,"第二" } }; 添加和輸出訪問
dict.Add(3,"第一個" ); foreach (var item in dict) { Console.WriteLine("Key:"
+item.Key+" Value:"+ item.Value); }
?
有序字典SortedDictionary<TKey,TValue>是一個二叉搜索樹,其中的元素根據(jù)建排序。和前面講的
SortedList<TKey,TValue>的功能類似。但是SortedList<TKey,TValue>
是基于數(shù)組的列表,而有序字典類為一個字典。多以它們也有不同之處:
*
* ?SortedList<TKey,TValue>使用的內(nèi)存比SortedDictionary<TKey,TValue>少
* ?SortedDictionary<TKey,TValue>的元素插入和刪除比較快
* ?在用已排好序的數(shù)據(jù)填充集合時,若不需要修改容量,SortedList<TKey,TValue>就比較快
六、集
包含不重復(fù)元素的的集合稱為”集(set)”,.Net Core 包含兩個集(HashSet<T>和SortedSet<T>),它們都實現(xiàn)ISet<T>
接口,HashSet<T>集包含不重復(fù)元素的無序列表,SortedSet<T>集包含不重復(fù)元素的有序列表。
ISet<T>接口提供的方法可以創(chuàng)建合集、交集,或者給出一個集是另一個集的超集或子集的信息。
? ? ? ?
static void Main(string[] args) { var teams = new HashSet<string>() { "one","
two","three"}; var teams1= new HashSet<string>() { "開始","one", "two", "three" };
//Add方法如果集中存在該元素則不添加,返回bool值 if (!teams.Add("one")) { Console.WriteLine("one
已經(jīng)存在集中"); } //IsSubsetOf方法判斷teams集合中的元素是否都包含在teams1中,返回bool值 if
(teams.IsSubsetOf(teams1)) { Console.WriteLine("teams中的值都包含在teams1中"); } //
IsSupersetOf方法判斷teams1集合是否是teams集合超集,返回bool值 if (teams1.IsSupersetOf(teams)) {
Console.WriteLine("teams1是teams的超集"); } //
Overlaps方法判斷teams集合與teams是否存在重疊的元素,返回bool值 if (teams.Overlaps(teams1)) {
Console.WriteLine("teams與teams1有重疊元素"); } }
?
總結(jié)
許多的集合都提供了相同的功能,例如SortedList類與SortedDictionary
類的功能幾乎完全相同。但是其性能常常差別非常巨大,一個集合使用的內(nèi)存少,另一個元素檢索起來速度快,在MSDN文檔中,集合的方法常常有性能的提示,給出以O(shè)
記號表示的操作時間:
*
* ?O(1)
* ?O(log n)
* ?O(n)
O(1)表示無論集合中有多少數(shù)據(jù)項,這個操作需要的時間都不變,例如,ArrayList類的Add()
方法就具有這個行為,無論列表有多少個集合,在列表末尾添加一個新元素的時間都相同。
O(n)表示對于集合執(zhí)行一個操作需要的時間最壞的情況是N,如果需要重新給集合分配內(nèi)存,ArrayList類的Add()方法就是一個O(n)
操作。改變?nèi)萘?,需要?fù)制列表,復(fù)制的時間隨元素的增加而線性的增加。
O(log n)表示操作需要的時間隨集合中元素的增加而增加,但每個元素要增加的時間不是線性的,而是呈對數(shù)曲線。在集合中執(zhí)行插入操作時,
SortedDictionary<TKey,TValue>集合類具有O(log n)行為,而SortedList<TKey,TValue>集合具有O(n)
行為,這里SortedDictionary<TKey,TValue>集合類就要快的多,因為樹形結(jié)構(gòu)中插入元素的效率比列表高的多。
下面表格中則列出了集合類及其執(zhí)行不同操作的性能??梢允褂眠@個表選擇性能最佳的集合類進行使用。
集合
Add
Insert
Remove
Item
Sort
Find
List<T>
如果集合必須重置大小就是O(1)或O(n)
O(n)
O(n)
O(1)
O(n log n)最壞情況O(n^2)
O(n)
Stack<T>(棧)
Push(),如果棧必須重置大小,就是O(1)或O(n)
no
Pop(),O(1)
no
no
no
Queue<T>(列隊)
Enqueue(),如果棧必須重置大小,就是O(1)或O(n)
no
Dequeu(),O(1)
no
no
no
HastSet<T>(無序列表)
如果棧必須重置大小,就是O(1)或O(n)
Add()
O(1)或O(n)
O(1)
no
no
no
LinkedList<T>(鏈表)
AddLast(),O(1)
AddAfter(),O(1)
O(1)
no
no
O(n)
?
?
最糟糕的是人們在生活中經(jīng)常受到錯誤志向的阻礙而不自知,真到擺脫了那些阻礙時才能明白過來?!璧?br>
?
歡迎大家掃描下方二維碼,和我一起學(xué)習(xí)更多的C#知識
?
熱門工具 換一換
感谢您访问我们的网站,您可能还对以下资源感兴趣:
调教肉文小说-国产成本人片免费av-空姐av种子无码-在线观看免费午夜视频-综合久久精品激情-国产成人丝袜视频在线观看软件-大芭区三区四区无码-啊啊好爽啊啊插啊用力啊啊-wanch视频网-国产精品成人a免费观看