一步一步学数据结构之(动态申请二维数组)

本文介绍如何使用二级指针动态申请二维数组,适用于邻接矩阵法实现图操作。文章提供了具体的C语言代码示例,展示了如何分配内存并初始化矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实现图操作的时候,因为用邻接矩阵法实现,所以就用到二维数组,而在这里,就着重说下怎么样动态申请二维数组,它的原理是:

申请完毕后,就类似于在一个一维数组中,每一个元素都为一个指针,而这个指针正好指向一个一维数组(或者说就是这个一维数组的首地址):

当然,动态申请二维数组和动态申请二级指针内存是一个道理,其实从动态申请二级指针也可以试着延伸到动态申请三级指针,甚至到n级指针。

现在截取下邻接矩阵法实现图时,创建矩阵的代码,以供参考:

MGraph* MGraph_Create(MVertex** v, int n)
{
	TMGraph* ret = NULL;
	
	if((NULL!=v) && (0<n))
	{
		ret = (TMGraph*)malloc(sizeof(TMGraph));
		
		if(NULL != ret)
		{
			int* p = NULL;
			
			ret->count = n;
			//通过二级指针动态申请一维指针数组 
			ret->v = (MVertex**)malloc(sizeof(MVertex*) * n);
			ret->matrix = (int**)malloc(sizeof(int*) * n);
			
			//通过一级指针申请数据空间
			//calloc函数把申请的数据空间全清0 
			p = (int*)calloc(n * n, sizeof(int));
			
			if((NULL!=ret->v) && (NULL!=ret->matrix) && (NULL!=p))
			{
				int i = 0;
				
				for(i=0; i<n; i++)
				{//把指针数组和数据空间连接起来 
					ret->v[i] = v[i];
					ret->matrix[i] = p + i* n;
				}	
			}
			else
			{
				free(ret->v);
				free(ret->matrix);
				free(p);
				free(ret);
				
				ret = NULL;	
			}	
		}
	}
	
	return ret;
}

### 使用指针替代二维数组的实现 在 C 语言中,可以利用一维指针来模拟二维数组的操作。通过这种方式,不仅可以减少内存开销,还可以提高灵活性。以下是具体的方法以及代码示例。 #### 方法说明 为了用指针代替传统的二维数组,可以通过动态分配一块连续的一维内存空间,并将其视为二维结构。假设有一个 `m` 行 `n` 列的二维数组,则可以用如下公式定位任意位置 `(i, j)` 的元素: ```c *(ptr + i * n + j) ``` 其中: - `ptr` 是指向这块一维内存区域的首地址; - `i` 和 `j` 分别表示行索引和列索引; - `n` 是每行的列数[^1]。 这种方法的核心在于将二维坐标映射到一维线性存储中的偏移量上。 --- #### 动态分配与释放内存 当使用指针替换传统静态定义的二维数组时,通常会采用动态内存管理技术(如 `malloc()` 或 `calloc()`),以便灵活调整大小或者处理更大的数据集。下面是一个完整的例子展示如何创建、初始化、操作并通过指针访问这样的伪二维数组。 --- #### 示例代码 以下是一段基于指针的二维数组实现代码: ```c #include <stdio.h> #include <stdlib.h> int main() { int m = 3; // 行数 int n = 4; // 列数 // 动态分配足够的空间给一个逻辑上的 mxn 大小的二维数组 int* ptr = (int*) malloc(m * n * sizeof(int)); if (!ptr) { // 检查是否成功申请到了所需的空间 printf("Memory allocation failed.\n"); return -1; } // 初始化该“二维”数组的内容 for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { *(ptr + i * n + j) = i * n + j + 1; // 填充一些简单的数值作为演示 } } // 输出整个“二维”数组的内容 printf("The matrix is:\n"); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { printf("%d\t", *(ptr + i * n + j)); // 显示当前单元格内的值 } putchar('\n'); // 移动至下一行继续打印下一个子列表项之前先换行 } // 计算所有元素之和 int totalSum = 0; for (int k = 0; k < m * n; ++k) { totalSum += *(ptr + k); } printf("Total Sum of all elements: %d\n", totalSum); free(ptr); // 不再需要的时候记得及时释放掉先前所请求下来的那片堆区资源以防泄露发生 return 0; } ``` 此程序展示了以下几个要点: 1. **动态分配**:通过调用 `malloc()` 函数为指定数量的整型变量预留必要的字节数目。 2. **填充过程**:按照特定规律设置每一个可能被引用的位置处的具体取值情况。 3. **遍历读写**:借助双重循环逐一访问目标范围内部的所有节点对象实例化后的表现形式。 4. **清理工作**:最后一步务必执行解除绑定动作以免造成不必要的浪费现象出现[^2]. --- #### 性能考量 相比于直接声明固定尺寸的多维表格而言,这种做法具备更高的适应能力同时也减少了部分冗余计算环节所带来的额外负担;然而需要注意的是,在频繁修改布局参数的情况下可能会引发更多的碎片问题从而影响整体效率水平[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值