###### tags: `C#`
# C#-資料結構API
* [Source Code](https://github.com/Chihhao/C_Sharp_Advance)
* [Burt Zhang](https://www.youtube.com/channel/UCnA36j_KoX-Z0QsayrLCsOg/videos) 這個頻道搜集了很多個Eleven老師的教學影片,非常精彩。
---
### 「陣列」Array, ArrayList, List
內存連續分配,可座標訪問,==讀取快,增刪慢==
* #### Array (固定類型)(固定長度)
```csharp
int[] intArray = new int[10];
intArray[0] = 87;
string[] strArray = new string[3] { "1", "22", "333" };
for (int i = 0; i < strArray.Length; i++) {
Console.WriteLine(strArray[i]);
}
```
* #### ArrayList (不固定類型)(不固定長度)
```csharp
ArrayList arrayList = new ArrayList(); //宣告時不知道有多長
arrayList.Add("0-Eleven"); //添加string數據,會增加長度
arrayList.Add("1-Eric");
arrayList.Add(2); //添加int數據,會增加長度
arrayList.Add(3);
arrayList.Add(4);
//arrayList[5] = 26; //這裡會Runtime error: 索引賦值時,不能增加長度
//arrayList.RemoveAt(5); //這裡會Runtime error: 超過範圍
arrayList.RemoveAt(3); //刪除數據 by index
arrayList.Remove("0-Eleven"); //刪除數據 by 內容 (滿足的第一個)
for (int i = 0; i < arrayList.Count; i++) {
Console.WriteLine(arrayList[i]);
}
```
* #### List (==泛型==)(不固定長度)(==最常用==)
```csharp
List<int> intList = new List<int>(); //宣告時不知道有多長
List<string> stringList = new List<string>(); //可以換成各種常用型別
stringList.Add("0-Eleven"); //添加數據,會增加長度
stringList.Add("1-Eric");
stringList.Add("2-Jack");
stringList.Add("3-Kevin");
//stringList[4] = "4-Susan"; //這裡會Runtime error: 索引賦值時,不能增加長度
//stringList.RemoveAt(4); //這裡會Runtime error: 超過範圍
stringList.RemoveAt(0); //刪除數據 by index
stringList.Remove("2-Jack"); //刪除數據 by 內容 (滿足的第一個)
for (int i = 0; i < stringList.Count; i++) {
Console.WriteLine(stringList[i]);
}
```
### 「鏈表」LinkedList, Queue, Stack
內存非連續分配,不可座標訪問,==增刪快,讀取慢==
* #### LinkedList (泛型)(不固定長度)
```csharp
LinkedList<int> intLinkList = new LinkedList<int>();
intLinkList.AddFirst(123);
intLinkList.AddFirst(456);
intLinkList.AddLast(4);
intLinkList.AddLast(5);
intLinkList.AddLast(6);
intLinkList.AddLast(7);
bool isContain = intLinkList.Contains(123); //是否包含某數據
LinkedListNode<int> node123 = intLinkList.Find(123); //找到節點
intLinkList.AddBefore(node123, 1); //在結點前添加數據
intLinkList.AddAfter(node123, 3); //在結點後添加數據
intLinkList.AddAfter(node123, 2); //在結點後添加數據
intLinkList.Remove(456);
intLinkList.Remove(node123);
intLinkList.RemoveFirst();
intLinkList.RemoveLast();
//查找不方便,如果不用foreach,就要靠一個一個串接下去查
foreach (int item in intLinkList) {
Console.WriteLine(item);
}
intLinkList.Clear();
```
* #### Queue (泛型)(不固定長度)(先進先出)
```csharp
Queue<string> stringQueue = new Queue<string>(); //建立隊列
stringQueue.Enqueue("one"); //加入隊列
stringQueue.Enqueue("two");
stringQueue.Enqueue("three");
stringQueue.Enqueue("four");
stringQueue.Enqueue("five");
foreach (string item in stringQueue) {
Console.WriteLine(item);
}
Console.WriteLine("離開隊列: " + stringQueue.Dequeue()); //先進先出,取出一個 (直接取出)
Console.WriteLine("下一個要離開隊列的是: " + stringQueue.Peek()); //先進先出,取出一個 (僅查詢)
Console.WriteLine("離開隊列: " + stringQueue.Dequeue());
//Queue可以轉成數組,也可利用數組建立Queue
Queue<string> copyQueue = new Queue<string>(stringQueue.ToArray());
foreach (string item in copyQueue) {
Console.WriteLine(item);
}
Console.WriteLine("隊列中是否包含four: " + copyQueue.Contains("four"));
Console.WriteLine("隊列中有幾個元素: " + copyQueue.Count);
copyQueue.Clear();
```
* #### Stack (泛型)(不固定長度)(後進先出)
```csharp
Stack<string> stringStack = new Stack<string>(); //建立堆疊
stringStack.Push("one"); //加入堆疊
stringStack.Push("two");
stringStack.Push("three");
stringStack.Push("four");
stringStack.Push("five");
foreach (string item in stringStack) {
Console.WriteLine(item);
}
Console.WriteLine("離開堆疊: " + stringStack.Pop()); //後進先出,取出一個 (直接取出)
Console.WriteLine("下一個要離開堆疊的是: " + stringStack.Peek()); //後進先出,取出一個 (僅查詢)
Console.WriteLine("離開堆疊: " + stringStack.Pop());
//Stack可以轉成數組,也可利用數組建立Stack
Stack<string> copyStack = new Stack<string>(stringStack.ToArray());
foreach (string item in copyStack) {
Console.WriteLine(item);
}
Console.WriteLine("隊伍中是否包含four: " + copyStack.Contains("four"));
Console.WriteLine("隊伍中有幾個元素: " + copyStack.Count);
copyStack.Clear();
```
### 「集合」HashSet, SortedSet
內存非連續分配,不可座標訪問,「**除去重複**」是集合最主要的價值
* #### HashSet (泛型)(不固定長度)(去重)(沒有順序)
```csharp
HashSet<string> stringHashSet = new HashSet<string>(); //建立集合
stringHashSet.Add("zero"); // 加入集合
stringHashSet.Add("one");
stringHashSet.Add("two");
stringHashSet.Add("three");
stringHashSet.Add("three"); // 重複元素,不會加入
stringHashSet.Add("three"); // 重複元素,不會加入
foreach (string item in stringHashSet) {
Console.WriteLine(item);
}
Console.WriteLine("集合中是否包含four: " + stringHashSet.Contains("four"));
Console.WriteLine("集合中有幾個元素: " + stringHashSet.Count);
//這是另一個集合
HashSet<string> hashSet_2 = new HashSet<string>(); //建立集合
hashSet_2.Add("one");
hashSet_2.Add("two");
hashSet_2.Add("three");
hashSet_2.Add("four");
hashSet_2.Add("five");
//兩個集合可以完成「交差併補」的操作: 交集/差集/聯集/補集
stringHashSet.SymmetricExceptWith(hashSet_2); //補集
stringHashSet.UnionWith(hashSet_2); //聯集 (並集)
stringHashSet.ExceptWith(hashSet_2); //差集
stringHashSet.IntersectWith(hashSet_2); //交集
```
* #### SortedSet (泛型)(不固定長度)(去重)(==有順序==)
```csharp
SortedSet<string> stringSortedSet = new SortedSet<string>(); //建立集合
stringSortedSet.Add("zero"); // 加入集合
stringSortedSet.Add("one");
stringSortedSet.Add("two");
stringSortedSet.Add("three");
stringSortedSet.Add("four");
stringSortedSet.Add("three"); // 重複元素,不會加入
foreach (string item in stringSortedSet) {
Console.WriteLine(item);
}
Console.WriteLine("集合中是否包含four: " + stringSortedSet.Contains("four"));
Console.WriteLine("集合中有幾個元素: " + stringSortedSet.Count);
```
### 「Key-Value型式」Hashtable, Dictionary, SortedDictionary
內存非連續分配,不可座標訪問,不能重複;
查找數據時,利用Key一次定位,==增刪快,讀取也快!== (空間換時間)(數據多效率會下降)
* #### Hashtable (object類型)(不固定長度)(資料不按加入順序)(無排序)
object 類型 --> 需要一定的轉換時間 --> 效能損失
```csharp
Hashtable hashtable = new Hashtable(); //建立哈希表
hashtable.Add("zero", "0000000000"); //利用Key與Value加入哈希表
hashtable.Add(1, "111111111"); //Key: 不固定類型
hashtable.Add("two", 2); //Value: 不固定類型
hashtable.Add("3", DateTime.Now);
hashtable.Add("four", "444");
//hashtable.Add("four", "555"); //Runtime error: 相同Key不能重複加入
hashtable.Add("four-2", "444"); //不同Key,相同Value,是可以的
foreach (DictionaryEntry objDE in hashtable) {
//一次拿到一對資料,包含一個Key一個Value
Console.WriteLine(objDE.Key.ToString() + "\t-\t" + objDE.Value.ToString());
}
Console.WriteLine("哈希表中是否包含Key=\"four\"的資料: " + hashtable.Contains("four"));
Console.WriteLine("哈希表中有幾個元素: " + hashtable.Count);
//線程安全,保證只有一個線程寫數據,其他線程只能讀
Hashtable mySyncdHT = Hashtable.Synchronized(hashtable);
Console.WriteLine("hashtable 是不是線程安全的? {0}", hashtable.IsSynchronized ? "是" : "否");
Console.WriteLine("mySyncdHT 是不是線程安全的? {0}", mySyncdHT.IsSynchronized ? "是" : "否");
```
* #### Dictionary (泛型)(不固定長度)(資料按加入順序)(無排序)
```csharp
Dictionary<int, string> dictionary = new Dictionary<int, string>(); //建立字典
dictionary.Add(1, "Jack"); //利用Key與Value加入字典
dictionary.Add(5, "Kevin");
dictionary.Add(3, "Bill");
dictionary.Add(2, "Pond");
dictionary.Add(4, "Eric");
//dictionary.Add(2, "Daniel"); //Runtime error: 相同Key不能重複加入
foreach (var item in dictionary) {
Console.WriteLine(item.Key + "\t-\t" + item.Value);
}
Console.WriteLine("字典表中是否包含Key=4的資料: " + dictionary.ContainsKey(4));
Console.WriteLine("字典表中是否包含Value=\"Jimmy\"的資料: " + dictionary.ContainsValue("Jimmy"));
Console.WriteLine("字典中有幾個元素: " + dictionary.Count);
//线程安全的字典
ConcurrentDictionary<int, string> concurrentDictionary =
new ConcurrentDictionary<int, string>(dictionary);
```
* #### SortedDictionary (泛型)(不固定長度)(資料按加入順序)(有排序)
```csharp
SortedDictionary<int, string> sortedDictionary = new SortedDictionary<int, string>(); //建立字典
sortedDictionary.Add(1, "Jack"); //利用Key與Value加入字典
sortedDictionary.Add(5, "Kevin");
sortedDictionary.Add(3, "Bill");
sortedDictionary.Add(2, "Pond");
sortedDictionary.Add(4, "Eric");
//sortedDictionary.Add(2, "Daniel"); //Runtime error: 相同Key不能重複加入
foreach (var item in sortedDictionary) {
Console.WriteLine(item.Key + "\t-\t" + item.Value);
}
Console.WriteLine("字典表中是否包含Key=4的資料: " + sortedDictionary.ContainsKey(4));
Console.WriteLine("字典表中是否包含Value=\"Jimmy\"的資料: " + sortedDictionary.ContainsValue("Jimmy"));
Console.WriteLine("字典中有幾個元素: " + sortedDictionary.Count);
```