當我們深入到程式設計的世界,我們會發現,掌握高階資料結構和演算法就像是擁有了一套高階工具箱,它們能幫助我們更高效、更優雅地解決問題。今天,我們就來一探究竟,看看這些高階工具是如何工作的。
首先,讓我們來談談高階資料結構。
資料結構就像是我們用來存放東西的容器,高階資料結構就是一些更復雜的容器。
它們就像是我們程式設計中的“儲存神器”,能讓我們以不同的方式組織和訪問資料。比如:
- 棧,它就像是一個只能從頂部放入和取出物品的容器,遵循“後進先出”的原則。
- 佇列,它則像是一個有序的隊伍,遵循“先進先出”的規則。
- 連結串列,它則提供了一種靈活的方式來儲存資料,每個資料點都指向下一個資料點,形成一個鏈條。
1. 棧、佇列、連結串列
棧(Stack)
想象一下你疊盤子。每次新放一個盤子都在最上面,拿走的時候也只能從最上面開始拿。這就是棧,後進先出(LIFO, Last In First Out)的資料結構。
// C#中使用Stack<T>類實現棧
using System.Collections.Generic;
public class StackExample
{
public static void Main()
{
Stack<int> myStack = new Stack<int>();
// 入棧:像疊盤子一樣新增元素
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
Console.WriteLine("Top element: " + myStack.Peek()); // 檢視但不移除頂部元素
// 出棧:移除並返回頂部元素
while (myStack.Count > 0)
{
Console.WriteLine("Popped: " + myStack.Pop());
}
}
}
佇列(Queue)
想象排隊買票,先來的先買,後來的後買。佇列就是這樣的,先進先出(FIFO, First In First Out)。
// 使用Queue<T>類實現佇列
using System.Collections.Generic;
public class QueueExample
{
public static void Main()
{
Queue<string> myQueue = new Queue<string>();
// 入隊:像排隊一樣加入元素
myQueue.Enqueue("Alice");
myQueue.Enqueue("Bob");
myQueue.Enqueue("Charlie");
Console.WriteLine("Front of queue: " + myQueue.Peek()); // 檢視隊首但不移除
// 出隊:移除並返回隊首元素
while (myQueue.Count > 0)
{
Console.WriteLine("Dequeued: " + myQueue.Dequeue());
}
}
}
連結串列(LinkedList)
連結串列就像是一串用繩子串起來的珠子,每個珠子(節點)都連著下一顆珠子。它不像陣列那樣連續儲存,所以插入和刪除操作更快,但訪問特定位置的元素較慢。
// 使用LinkedList<T>類實現連結串列
using System.Collections.Generic;
public class LinkedListExample
{
public static void Main()
{
LinkedList<int> myList = new LinkedList<int>();
// 插入節點
myList.AddFirst(3); // 在頭部新增
myList.AddLast(5); // 在尾部新增
myList.AddBefore(myList.First, 2); // 在第一個元素前新增
// 遍歷連結串列
foreach (int value in myList)
{
Console.WriteLine(value);
}
}
}
2. 排序和搜尋演算法
接下來是排序和搜尋演算法,它們是我們在處理大量資料時的好幫手。排序演算法幫助我們把資料排成有序的序列,而搜尋演算法則幫助我們快速找到所需的資料。
排序演算法(以氣泡排序為例)
氣泡排序就像是玩撲克牌,每次比較相鄰兩張,如果順序不對就交換,一輪輪下來,最大的牌就像泡泡一樣浮到最上面。
public static void BubbleSort(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++) // 每輪少比較一次
{
if (arr[j] > arr[j + 1]) // 如果前一個大於後一個,交換
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
搜尋演算法(線性搜尋)
線性搜尋就像是在書架上找一本書,從頭開始一本本檢查,直到找到為止。
public static int LinearSearch(int[] arr, int target)
{
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == target)
{
return i; // 找到了,返回位置
}
}
return -1; // 沒找到,返回-1
}
3. 泛型程式設計
最後,我們還有泛型程式設計,這是一種編寫程式碼的方式,它允許我們建立可以處理多種資料型別的元件,使得程式碼更加通用和靈活。
比如能夠處理多種資料型別的程式碼,不用為每種型別重複寫相似邏輯。就像製作一個“萬能模具”,不管是做蛋糕還是麵包,只要換原料就行。
// 泛型方法示例
public static T Max<T>(T a, T b) where T : IComparable<T>
{
return a.CompareTo(b) > 0 ? a : b;
}
public static void Main()
{
Console.WriteLine(Max(10, 20)); // 整數比較
Console.WriteLine(Max("apple", "banana")); // 字串比較
}
透過泛型,我們讓Max
方法既能比較整數大小,也能比較字串的字典序,無需為每種型別單獨寫函式。