矩阵在数据结构与算法的课程中也是非常重要的一章。矩阵也是一种存储数据的方式,所以本人通过这一章来对矩阵进行一下讲解以及说明。
首先,我来提出一个很常见的面试题:
请编写一个通用的二维数组(用c实现):
这个问题相对而言比较简单,一个二维数组重要的只有三点,即:横下标、纵下标、值,所以我们来构建如下结构体:
typedef struct MATRIX {
USER_TYPE *data; //这里的USER_TYPE类型是用户自己定义的类型,而我们用它的指针作为结构体的成员,这样使得所有存储在二维数组中的数据都能够通过这个成员被访问
int maxRow; //这个成员用于存储最大行数
int maxCol; //这个成员用于存储最大列数
}MATRIX;
在这里,我们发现,其实传过来的USER_TYPE *类型其实表示的是一维数组,但是我们需要表示二维数组,所以我还要提到一个当初我们学习数组时的知识点,那就是所有的数组在内存中的存储方式都和一维数组一样,所以,所有维的数组都可以通过一维数组改变而成,现在我来给出一个公式:
arr[i][j] == arr[i*maxCol+j] //这里的==是等价于的意思
那么,为什么我要讲到这个面试题呢?其实细心的同学可能已经发现了,矩阵其实就是一个二维数组
现在有了之前的铺垫,我们就开始实现一下矩阵吧。
首先,还是编写"mec.h"头文件:
#ifndef _MEC_H_
#define _MEC_H_
typedef unsigned char boolean;
typedef boolean u8;
#define TRUE 1
#define FALSE 0
#define SET(v, i) (v |= (1 << ((i) ^ 7)))
#define CLR(v, i) (v &= ~(1 << ((i) ^ 7)))
#define GET(v, i) (((v) & (1 << ((i) ^ 7))) != 0)
#endif
结构体我们在上面已经构建过了,那么,我们就来实行处理矩阵数据的操作吧:
由我们对于矩阵的了解,对于矩阵内的数据的操作,其实也就是取数据和存数据,那么,就得先有一个矩阵,所以,要先初始化一个矩阵,那么,我们现在先编写初始化矩阵的函数:
至于返回值,因为可能会初始化失败,所以肯定是boolean型(这个类型的定义在我们自己编写的"mec.h"头文件中),而参数,就是矩阵和最多行数和最多列数
boolean initMatrix(MATRIX **matrix, int maxRow, int maxCol) {
if (NULL == matrix || NULL != *matrix
|| maxRow <= 0 || maxCol <= 0 || maxRow * maxCol > MAX_ROOM) {
return FALSE;
}
*matrix = (MATRIX *) calloc(sizeof(MATRIX), 1);
(*matrix)->data = (USER_TYPE *) calloc(sizeof(USER_TYPE), maxRow * maxCol);
(*matrix)->maxRow = maxRow;
(*matrix)->maxCol = maxCol;
return TRUE;
}
有了初始化,就要想到销毁,所以,现在我们来编写销毁函数:
void destoryMatrix(MATRIX **matrix) {
if (NULL == matrix || NULL == *matrix) {
return;
}
free((*matrix)->data);
free(*matrix);
*matrix = NULL;
}
接下来就是存数据的操作了,但是,存的数据不能超出矩阵的范围,所以,我们来编写判最大行数和判最大列数的函数:
int getMaxRow(const MATRIX *matrix) {
return NULL == matrix ? -1 : matrix->maxRow;
}
int getMaxCol(const MATRIX *matrix) {
return NULL == matrix ? -1 : matrix->maxCol;
}
万事俱备,我们来编写存数据的函数:
boolean setElementAt(const MATRIX *matrix, int row, int col, const USER_TYPE value) {
if (NULL == matrix
|| row < 0 || row > matrix->maxRow
|| col < 0 || col > matrix->maxCol) {
return FALSE;
}
matrix->data[row * matrix->maxCol + col] = value;
return TRUE;
}
最后就是取数据函数:
关于参数得说明一点,因为返回值为boolean 型(判断操作是否正确),所以要用一个USER_TYPE *类型的参数将最终取出的值“返回”到主函数中
boolean getElementAt(const MATRIX *matrix, int row, int col, USER_TYPE *value) {
if (NULL == matrix
|| row < 0 || row > matrix->maxRow
|| col < 0 || col > matrix->maxCol) {
return FALSE;
}
*value = matrix->data[row * matrix->maxCol + col];
return TRUE;
}