数组(矩阵)工具
一、数组的优缺点
1.优点:
1、按照索引查询元素速度快
2、能存储大量数据
3、按照索引遍历数组方便
2.缺点:
1、根据内容查找元素速度慢
2、数组的大小一经确定不能改变。
3、数组只能存储一种类型的数据
4、增加、删除元素效率慢
5、未封装任何方法,所有操作都需要用户自己定义。
摘自文章数组优缺点总结
二、循环数组
1.作用:
为了避免数组的整体移动,使用循环数组。
2.简单说明
将一组数据,标记上两个下标(head)和(tail)。当数据移动时,不需要通过一个个复制,来实现移动。只需要将tail 和head的移动就可以实现。
数据移动: 一组数据中,每次操作会删除或增加新数据,但大部分数据可以保留。
3.实现
- 下标移动
#define capacity 5
int array[capacity] = {1,2,3,4,5};
int head = 0;
int tail = 0;
//有效数据12345
head = 4; // 元素头指针
//增加6,删除1
head = (head + 1) % capacity;
tail = (tail + 1) % capacity;
array[head] = 6;//增加6
for (; tail == head; tail = (tail + 1) % capacity) {
printf("%05d", array[tail]); //输出23456
}
head = (head + 1) % capacity; 当 head = capacity - 1 时,操作时,head = 0,形成循环。
4.适用地方
1.贪吃蛇的蛇身数据存储
2.队列工具的实现
3.各种数据移动类
二、通用一维数组
什么是通用一维数组?起码能适用于各种类型。
1.数据类型通用(void *)
思考: 数据类型不同,有长有短,但是数据首地址都是4B。是一样的。
所以使用void *就可以将不同数据的是首地址保存。
那么这个数值可以申请为 *void array[capacity];
采用动态存储分配可以这样:
typedef struct NORMAL_MATRIX {
void **data;
int capacity;
}NORMAL_MATRIX;
//初始化
NORMAL_MATRIX array;
array.data = (void **) calloc(sizeof(void *), array.capacity);
void **小解释:
//解释
typedef struct STU {
int score;
...
}STU;
void **data = NULL;
data = (void **)calloc(sizeof(void *), n);
int num = 30;
char str[8] = "12345678";
STU stu1 = {...};//结构体
data[0] = #
data[1] = str; (&str[0] <=> &*(str + 0) <=> str)
data[2] = stu1;
//下面是图片
三、通用二维数组工具
其实,一维数组明白之后,二维数组也就轻松了。二维数组某种程度称之为二阶矩阵。
1.控制元素
typedef struct NORMAL_MATRIX {
void **data;
int rowCount;//行阶
int colCount;//列阶
}NORMAL_MATRIX;
2.基本功能实现
初始化和销毁:
boolean initMatrix(NORMAL_MATRIX **matrix, int rowCount, int colCount) {
if (NULL == matrix || NULL != *matrix || rowCount <= 0 || colCount <= 0) {
return FALSE;
}
*matrix = (NORMAL_MATRIX *) calloc(sizeof(NORMAL_MATRIX), 1);
if (NULL == *matrix) {
return FALSE;
}
(*matrix)->data = (void **) calloc(sizeof(void *), rowCount * colCount);
if (NULL == (*matrix)->data) {
free(*matrix);
*matrix = NULL;
return FALSE;
}
(*matrix)->rowCount = rowCount;
(*matrix)->colCount = colCount;
return TRUE;
}
//销毁二维数组(矩阵)
void destory(NORMAL_MATRIX **matrix) {
if (NULL == matrix ||NULL == *matrix) {
return;
}
free((*matrix)->data);
free(*matrix);
*matrix = NULL;
}
存储数与读取数:
//指定下标率录入元素
boolean setElementAt(const NORMAL_MATRIX *matrix, const int row, const int col, void *data) {
if (NULL == matrix
|| row < 0 || row >= matrix->rowCount
|| col < 0 || col >= matrix->colCount
|| NULL == data) {
return FALSE;
}
matrix->data[row * matrix->colCount + col] = data;
return TRUE;
}
//指定下标读取数据
void *getElementAt(const NORMAL_MATRIX *matrix, const int row, const int col) {
if (NULL == matrix
|| row < 0 || row >= matrix->rowCount
|| col < 0 || col >= matrix->colCount) {
return FALSE;
}
return matrix->data[row *matrix->colCount + col];
}
ps:二维数组本质也是一维数组,所以这里只要处理好一维数组下标与二维数组之间关系就可以了。
四、总结
- 每一中数据结构都有其优缺点。更有其适用地方。灵活应用,才能更好解决问题。
- void* 的得到,属于对各个数据求同的结果。刚开始还模糊,用的多了就越来越得心易手。
- 通用。
笔者水平有限,目前只能描述以上问题,如果有其他情况,可以留言,有错误,请指教,有继续优化的,请分享,谢谢!
完整代码如下:
matrix.h:
#ifndef _SL_MATRIX_H_
#define _SL_MATRIX_H_
#define TRUE 1
#define FALSE 0
typedef unsigned char boolean;
typedef struct NORMAL_MATRIX {
void **data;
int rowCount;
int colCount;
}NORMAL_MATRIX;
boolean initMatrix(NORMAL_MATRIX **matrix, int rowCount, int colCount);
void destory(NORMAL_MATRIX **matrix);
boolean setElementAt(const NORMAL_MATRIX *matrix, const int row, const int col, void *data);
void *getElementAt(const NORMAL_MATRIX *matrix, const int row, const int col);
#endif
matrix.c:
#include <stdio.h>
#include <malloc.h>
#include "matrix.h"
//初始化二维数组(矩阵)
boolean initMatrix(NORMAL_MATRIX **matrix, int rowCount, int colCount) {
if (NULL == matrix || NULL != *matrix || rowCount <= 0 || colCount <= 0) {
return FALSE;
}
*matrix = (NORMAL_MATRIX *) calloc(sizeof(NORMAL_MATRIX), 1);
if (NULL == *matrix) {
return FALSE;
}
(*matrix)->data = (void **) calloc(sizeof(void *), rowCount * colCount);
if (NULL == (*matrix)->data) {
free(*matrix);
*matrix = NULL;
return FALSE;
}
(*matrix)->rowCount = rowCount;
(*matrix)->colCount = colCount;
return TRUE;
}
//销毁二维数组(矩阵)
void destory(NORMAL_MATRIX **matrix) {
if (NULL == matrix ||NULL == *matrix) {
return;
}
free((*matrix)->data);
free(*matrix);
*matrix = NULL;
}
//指定下标率录入元素
boolean setElementAt(const NORMAL_MATRIX *matrix, const int row, const int col, void *data) {
if (NULL == matrix
|| row < 0 || row >= matrix->rowCount
|| col < 0 || col >= matrix->colCount
|| NULL == data) {
return FALSE;
}
matrix->data[row * matrix->colCount + col] = data;
return TRUE;
}
//指定下标读取数据
void *getElementAt(const NORMAL_MATRIX *matrix, const int row, const int col) {
if (NULL == matrix
|| row < 0 || row >= matrix->rowCount
|| col < 0 || col >= matrix->colCount) {
return FALSE;
}
return matrix->data[row *matrix->colCount + col];
}
2020年03.07 家