引言:为什么算法与数据结构是掌握C#的基础
任何希望用C#编写高效、可扩展代码的开发者,迟早都会面临理解算法与数据结构工作原理的需求。这不仅仅是学术理论——它是一种工具,能让你针对具体问题选择正确的解决方案:无论是从百万条记录中查找元素、对订单列表进行排序,还是实时处理数据。
在本文中,我们将通过C#(.NET)的实践示例来解析关键概念。你将了解什么是算法复杂度(Big O)、.NET内置了哪些数据结构以及如何使用它们。本材料面向初学者:我们将从简单内容开始,逐步深入细节。
1. 基础:C#中的数据结构与算法是什么
1.1 数据结构的概念
数据结构是在计算机内存中组织和存储数据的方式。在C#(.NET)中,我们既有内置结构(数组、列表、字典),也可以创建自定义结构。正确选择数据结构直接影响应用程序的性能。
1.2 算法的概念
算法是解决问题的步骤序列。例如,冒泡排序算法或二分查找。重要的不仅是知道如何编写代码,还要理解针对特定数据量应选择哪种算法。
1.3 复杂度评估(Big O表示法)
Big O描述了算法执行时间随输入数据增长而增长的方式。主要表示法:
O(1)— 常数时间(通过索引访问数组元素)O(n)— 线性时间(在未排序列表中查找)O(log n)— 对数时间(二分查找)O(n²)— 平方时间(冒泡排序)
在C#中,可以使用System.Diagnostics.Stopwatch测量执行时间。
using System.Diagnostics;
int[] data = { 5, 3, 8, 1, 9 };Stopwatch sw = Stopwatch.StartNew();Array.Sort(data); // 内置排序 O(n log n)sw.Stop();Console.WriteLine($"排序耗时:{sw.ElapsedMilliseconds} 毫秒");2. C#(.NET)中的主要数据结构
2.1 数组(Array)
数组是固定大小的同类型元素集合。在C#中,数组索引从0开始。当元素数量已知时,数组是理想选择。
int[] numbers = new int[5] { 10, 20, 30, 40, 50 };Console.WriteLine(numbers[2]); // 输出:30// 尝试越界访问会引发 IndexOutOfRangeException使用场景:需要按索引快速访问(O(1))。不适合频繁添加/删除元素。
2.2 列表(List<T>)
来自System.Collections.Generic命名空间的动态数组。添加元素时会自动扩容。这是C#中最常用的结构之一。
List<string> fruits = new List<string>();fruits.Add("苹果");fruits.Add("香蕉");fruits.Insert(1, "橙子"); // 在位置1插入Console.WriteLine(fruits.Count); // 输出:3使用场景:需要频繁在列表末尾添加元素(均摊O(1))。在中间插入为O(n)。
2.3 字典(Dictionary<TKey, TValue>)
基于哈希表的“键-值”集合。允许通过键快速查找值。
Dictionary<string, int> ages = new Dictionary<string, int>();ages["安娜"] = 25;ages["鲍里斯"] = 30;
if (ages.ContainsKey("安娜")){ Console.WriteLine($"安娜的年龄:{ages["安娜"]}"); // 输出:25}使用场景:用于查找