数组
数组的类型定义
- 数组的组成:下标、值
- 数组的特点:元素属于同一种数据类型、具有固定格式和数量的数据集合
数组的顺序表示和实现
- 数组的存储结构:数组是多维结构,而存储空间是一个一维的结构
- 二维数组的存储域寻址——不同的存储方式有不同元素地址计算方法:大部分按行优先
矩阵的压缩存储
- 特俗矩阵的压缩存储:稀疏矩阵(矩阵中有许多特定的值)、特殊矩阵(矩阵中很多值相同的元素并且它们的分布有一 定的规律)
- 压缩存储的基本思想:为多个值相同的元素只分配一个存储空间、对特定值的(如零)元素不分配存储空间
- 稀疏矩阵:稀疏矩阵的三元组顺序表存储
广义表
广义表是递归定义的线性结构
广义表的结构特点
- 广义表中的数据元素有相对次序
2)广义表的长度定义为最外层包含元素个数
3)广义表的深度定义为所含括弧的重数:“原子”的深度为 0、“空表”的深度为 1
4)广义表可以共享(不必列出子表的值,而是通过子表的名称来引用)
5)广义表可以是一个递归的表。递归表的深度是无穷值,长度是有限值
广义表的存储结构
- 广义表从结构上可以分解成 :1.表头、表尾分析法 ——广义表 = 表头 + 表尾。2.子表分析法——广义表 = 子表1 + 子表2 + ··· + 子表n
三元矩阵的快速转置
结构体的定义
typedef struct elem
{
int i,j;//i为行,j为列
int e;//e为数据
}Elem;
typedef struct matrix
{
Elem data[MAX+1];//存储数据的数组头
int nu,mu,tu;//行数、列数、非零元素数
}Matrix,*pMatrix;
三元矩阵的快速转置算法
- 这里,我们是假设已经有了排好序的三元矩阵,而这个算法要做的是对三元矩阵进行快速转置,时间复杂度为O(n)。
- 这里,我们会用到辅助的数组num[ ](用于记录转置前每一列的非零个数、即对应转置后每一行的非零个数)、cpot[ ](用于记录转置前每一列的第一个元素转置后的位置),实现以上的功能只需两个for循环即可。
- 最后,我们要开始进行转置。这个时候,我们要知道比较关键的二个信息:1.还未转置的三元组矩阵是有序的(即按先行后列的次序递增)。2.cpot[ ]数组记录了每一列的第一个元素转置后应该在的位置。
- 由数学知识我们知道,我们要得到转置后有序的三元组,只需让原本的三元组从第一个开始进行转置,一一对应地插入cpot[ ]数组所记录的位置,假设三元组的第一个转置的为第i行,第j列,转置后为第j行,第i列。转置成功并插入后,我们需把对应cpot[j]++(是因为++后cpot就变成记录该列的下一个元素转置后对应插入新三元表的位置)。
- 执行以上步骤,直至三元组转置完成。
源代码
#include<stdio.h>
#include<stdlib.h>
#define MAX 1000
typedef struct elem
{
int i,j;//i为行,j为列
int e;//e为数据
}Elem;
typedef struct matrix
{
Elem data[MAX+1];//存储数据的数组头
int nu,mu,tu;//行数、列数、非零元素数
}Matrix,*pMatrix;
void CreateMatrix(pMatrix M);//创建三维数组的
void Print(pMatrix M);//打印三维数组
pMatrix Invert(pMatrix M1);//快速转置
int main()
{
pMatrix M1,M2;
M1=(pMatrix)malloc(sizeof(Matrix));
M1->tu=0;//初始化数据
CreateMatrix(M1);
Print(M1);
M2=Invert(M1);
Print(M2);
}
void CreateMatrix(pMatrix M)
{
int i=1;
int n,m,e;
int col,row;
printf("Please input the row and column:(example: 10 25)\n");
scanf("%d %d",&row,&col);
getchar();
M->nu=row;
M->mu=col;
printf("Please input the elem of matrix:\n");
printf("Example: 1 2 10\n");
printf("when you complete you input,you can input -1 -1 -1.\n");
while(1)//读入数据
{
scanf("%d %d %d",&n,&m,&e);
getchar();
if(n==-1&&m==-1&&e==-1)
{
break;
}
else
{
M->data[i].i=n;
M->data[i].j=m;
M->data[i].e=e;
M->tu++;
i++;
}
}
}
void Print(pMatrix M)
{
int i;
printf("These is the data about the matrix:\n");
printf("row: %d column: %d elem number: %d\n",M->nu,M->mu,M->tu);
printf("row col elem\n");
for(i=1;i<=M->tu;i++)//for循环打印数据
{
printf("%d %d %d\n",M->data[i].i,M->data[i].j,M->data[i].e);
}
}
pMatrix Invert(pMatrix M1)
{
pMatrix M2;
M2=(pMatrix)malloc(sizeof(Matrix));
int i;
int num[MAX],cpot[MAX];
M2->tu=M1->tu;//数据复制
M2->nu=M1->nu;
M2->mu=M1->mu;
for(i=1;i<=M1->mu;i++)//初始化数组
{
num[i]=0;
cpot[i]=0;
}
for(i=1;i<=M1->tu;i++)//计算每一列的非零个数
{
num[M1->data[i].j]++;
}
cpot[1]=1;//初始化第一个位置
for(i=2;i<=M1->mu;i++)//计算每列的第一个元素转置后的位置
{
cpot[i]=cpot[i-1]+num[i-1];
}
for(i=1;i<=M1->tu;i++)//开始转置
{
M2->data[cpot[M1->data[i].j]].i=M1->data[i].j;
M2->data[cpot[M1->data[i].j]].j=M1->data[i].i;
M2->data[cpot[M1->data[i].j]].e=M1->data[i].e;
cpot[M1->data[i].j]++;//应在的位置加一
}
return M2;
}


本文介绍了数组和广义表的概念,包括数组的存储结构、特殊矩阵的压缩存储,特别是稀疏矩阵的三元组顺序表存储。接着讲解了广义表的递归定义和深度、长度的概念,以及其存储结构。最后,文章重点讨论了三元矩阵的快速转置算法,包括所需的数据结构和时间复杂度,并给出了转置过程的关键步骤。
1500

被折叠的 条评论
为什么被折叠?



