C# 交错数组(建议收藏)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言

在编程中,数组是一种基础且重要的数据结构。但当需要处理的数据规模或形状不规则时,传统的矩形数组(如二维数组)可能无法满足需求。此时,C# 交错数组(Jagged Array)便展现出其独特优势。它允许每个子数组的长度不同,适用于表格数据、分层结构或不规则形状的场景。本文将从基础概念、实现方法到实际案例,系统讲解交错数组的使用技巧与核心原理,帮助开发者高效管理复杂数据。


什么是 C# 交错数组?

定义与特点

C# 交错数组是一种“数组的数组”,即每个元素本身也是一个数组。其核心特点是:

  • 子数组长度可变:同一层级的子数组可以有不同的长度。
  • 内存分配灵活:每个子数组独立分配内存,避免矩形数组因固定长度导致的内存浪费。
  • 访问效率高:通过双重索引快速定位元素,如 array[i][j]

形象比喻:可以将交错数组想象为一个图书馆的书架,每一层书架(子数组)存放的书籍数量不同,但整体通过书架的编号(主索引)和书籍的顺序(子索引)来定位。

与矩形数组的对比

现有数组类型定义方式元素存储方式适用场景
矩形数组int[,]固定行列长度规则表格、棋盘等
交错数组int[][]子数组长度可变不规则数据、分层结构

例如,若要存储某公司不同部门的员工数量,若部门人数不固定,使用交错数组更合理:

int[][] departmentMembers = {  
    new int[] {5, 3}, // 技术部(小组1有5人,小组2有3人)  
    new int[] {8},    // 销售部(仅1个小组)  
    new int[] {2, 4, 6} // 财务部(3个小组)  
};  

如何创建与初始化交错数组?

基础语法与步骤

创建交错数组需分两步:

  1. 声明主数组:定义主数组的类型和长度。
  2. 初始化子数组:为每个主数组元素分配独立的子数组。

示例1:直接初始化

// 声明主数组(长度为3)  
int[][] jaggedArray = new int[3][];  

// 初始化每个子数组  
jaggedArray[0] = new int[] {1, 2, 3}; // 子数组长度为3  
jaggedArray[1] = new int[] {4, 5};    // 子数组长度为2  
jaggedArray[2] = new int[] {6};       // 子数组长度为1  

示例2:单行初始化(更简洁)

int[][] jaggedArray = new int[][] {  
    new int[] {10, 20},  
    new int[] {30, 40, 50},  
    new int[] {60}  
};  

动态扩展子数组

若需在运行时动态调整子数组的长度,可使用 Array.Resize 或重新赋值:

// 原子数组长度为2  
jaggedArray[0] = new int[] {1, 2};  

// 动态扩展为长度3  
Array.Resize(ref jaggedArray[0], 3);  
jaggedArray[0][2] = 3; // 新元素赋值  

访问与遍历交错数组

元素访问

通过双重索引访问元素,如 array[主索引][子索引]

int value = jaggedArray[1][2]; // 获取第二个子数组的第三个元素(50)  

安全性注意事项

由于子数组长度不固定,需避免越界访问。建议使用 GetLength 或循环条件判断:

// 获取子数组长度  
int subLength = jaggedArray[i].Length;  

// 安全遍历子数组  
for (int j = 0; j < subLength; j++) {  
    Console.WriteLine(jaggedArray[i][j]);  
}  

多重循环遍历

使用嵌套循环遍历整个数组:

for (int i = 0; i < jaggedArray.Length; i++) {  
    for (int j = 0; j < jaggedArray[i].Length; j++) {  
        Console.Write(jaggedArray[i][j] + " ");  
    }  
    Console.WriteLine();  
}  

输出结果:

10 20  
30 40 50  
60  

实际案例:销售数据的动态管理

假设某公司需要记录不同月份的销售数据,且每月的周数不同(如闰年或非整月统计)。使用交错数组可灵活存储:

double[][] monthlySales = new double[12][];  

// 初始化各月数据(假设数据不规则)  
monthlySales[0] = new double[] { 1500, 1800, 2100 }; // 1月3周数据  
monthlySales[1] = new double[] { 1700, 1600, 1900, 2000 }; // 2月4周数据  
// ... 其他月份类似  

// 计算某月总销售额  
int monthIndex = 0;  
double total = 0;  
foreach (double sale in monthlySales[monthIndex]) {  
    total += sale;  
}  
Console.WriteLine($"1月总销售额:{total}"); // 输出 5400  

性能与注意事项

内存分配优势

交错数组的内存分配更高效:

  • 矩形数组需预先分配所有元素的空间,即使某些行未被使用。
  • 交错数组仅占用实际子数组的内存,适合不规则数据。

访问速度

由于每个子数组独立存储,访问时需两次内存寻址(先主数组,再子数组),速度略低于矩形数组。但在数据不规则场景下,这种牺牲是值得的。

典型错误与解决

  1. 空引用异常:若未初始化子数组直接访问。

    // 错误示例  
    int[][] arr = new int[3][];  
    Console.WriteLine(arr[0][0]); // 抛出NullReferenceException  
    

    解决方法:确保每个子数组已初始化。

  2. 索引越界:访问超出子数组长度的元素。
    解决方法:使用 Length 属性验证索引范围。


结论

C# 交错数组为处理不规则数据提供了灵活且高效的解决方案。通过理解其“数组的数组”特性,开发者可以更自如地应对分层结构、动态数据集等复杂场景。无论是销售统计、游戏地图设计,还是科学计算中的不规则网格,交错数组都能通过其动态扩展能力和内存管理优势,成为代码优化的关键工具。

掌握交错数组的核心在于:

  1. 熟练初始化与访问语法;
  2. 注意子数组的独立性与安全性;
  3. 根据实际需求选择交错数组或矩形数组。

通过本文的案例与代码示例,相信读者已能将 C# 交错数组 应用于实际项目中,提升数据管理的灵活性与效率。

最新发布