---
# System prepended metadata

title: C#-資料結構API
tags: [C#]

---

###### 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);  
```





