稀疏数组
/*
* @Author: itThree
* @Date: 2021-09-10 15:48:10
* @LastEditTime: 2021-09-15 15:58:50
* @Description:
* @FilePath: cppdatassparseArr.cpp
* 光阴之逆旅,百代之过客,而已
*/
#include<stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void printArr(int *arr, int row, int col);
/**
* 稀疏数组:将二维数组进行“压缩”;
* 使用n+1行3列,其中n为原数组中有效(非零)元素个数,稀疏数组第0行用于存放行、列、元素总数信息故需n+1行
*/
//统计数组中元素的个数,用于确定稀疏数组的行数
int countElement(int* &p, int row, int col){
int sum;
int n = row*col;
for(int i=0; i<n; i++){
if(*(p+i) != 0){
sum++;
}
}
printf("sum: %d
",sum);
return sum;
}
//以指针形式接收矩阵(二维数组)
void createSparseArr2(int* arr, int row, int col ,int n){
int sparse[n+1][3];
sparse[0][0] = row;
sparse[0][1] = col;
sparse[0][2] = n;
int sparseRow = 0;
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(*(arr+i*col+j)!=0){
sparseRow++;
sparse[sparseRow][0] = i;
sparse[sparseRow][1] = j;
sparse[sparseRow][2] = *(arr+i*col+j);
}
}
}
printArr((int*)sparse,n+1,3);
}
//这个稀疏数组的存储算法为n^2,还可用指针实现一个n。
//打印二维数组
void printArr(int *arr, int row, int col)
{//指针指向二维数组首地址,依靠row,col判别边界条件
//遍历行
for(int i=0;i<row;i++){
//遍历列
for(int j=0;j<col;j++)printf("%d ",*(arr+i*col+j));
printf("
");
}
}
int main(){
int source[4][8]{
{1,7,6,5,2,8,2,8},
{2,7,6,5,2,8,2,8},
{3,7,6,5,2,8,2,8},
{4,7,6,5,2,8,2,8}
};
int* p;
p = source[0];
int n = countElement(p,4,8);
printf("-------------------------------------------
");
createSparseArr2((int*)source,4,8,n);
//int* i[4];
//指针i指向二维数组的一行
//i[0] = source[0];
//i[1] = source [1];
//i[2] = source [2];
//i[3] = source [3];
// createSparseArr1(i,4,8,n);
return 0;
}
使用指针数组方式创建稀疏数组
//使用指针数组传值
void createSparseArr1(int* p1[], int row, int col, int n){
//需要多一行来存储原数组大小信息
int sparse[n+1][3];
sparse[0][0] = row;
sparse[0][1] = col;
sparse[0][2] = n;
//控制稀疏数组的行号
int sparseRow = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{ //原数数组索引处有无元素为判断条件,有则放入稀疏数组,无则进行下一次循环
if(p1[i][j]!=0){
//第0行已存放数据,故先行++
sparseRow++;
sparse[sparseRow][0] = i;
sparse[sparseRow][1] = j;
sparse[sparseRow][2] = p1[i][j];
}
}
}
printArr((int*)sparse,n+1,3);
}
遇到的问题:
强制转换数组首地址为指针返回不可行
报错的地方:
int sparse[n+1][3];
return (int*) sparse;
解答:在函数执行完毕并return后sparse数组将被销毁,故无法将其强制转换为指针类型并返回;
不过,指定一个指针指向sparse并返回倒不成问题。
指针与数组地址
int source[4][8]{
{1,7,6,5,2,8,2,8},
{2,7,6,5,2,8,2,8},
{3,7,6,5,2,8,2,8},
{4,7,6,5,2,8,2,8}
};
int* p;
p = source[0];
int* i[4];
//指针i指向二维数组的一行
i[0] = source[0];
i[1] = source [1];
i[2] = source [2];
i[3] = source [3];
//得出结果
// source[0],source[0][0]在同一地址下
printf("p: %d
", p);
printf("source[0]: %d
", source[0]);
printf("&source[0][0]: %d
", &source[0][0]);
printf("source[0][0]: %d
", source[0][0]);
printf("*p: %d
", *p);
//使用指针数组指向二维数组每行首地址可行
printf("i[1][i]: %d
", i[1][2]);
printf("*(p+31) %d
", *(p+31));
//下标溢出了哦!
printf("*(p+32) %d
", *(p+32));
运行结果: