BDS之数组与矩阵
来源:互联网 发布:人工智能行动计划 编辑:程序博客网 时间:2024/05/18 03:07
数组
数组是将相同数据类型的元素按照一定顺序排列而成的集合。由于存储单元是一维结构,而数据是多维的结构,则用一组连续存储单元存放数组元素就有个次序约定问题,这也就是数组结构产生的原因。
下面我们看下简单的数组是如何实现的:
#define MAX_ARRAY_DIM 8#define ERROR -1#define OK 0#define UNDERFLOW 4#define OVERFLOW -2typedef int Status;struct Array{ElemType* base; //数组元素基址 int dim; //数组维数int *bounds; //数组维界基址int *constants;//数组映像函数常量基址};//init arrayStatus init_array(Array &A,int dim,...){int elemtotal = 1,i;va_list ap;if(dim<1 || dim>MAX_ARRAY_DIM)return ERROR;A.dim = dim;A.bounds = (int*)malloc(dim*sizeof(int));if(!A.bounds)return ERROR;va_start(ap,dim);for(i=0;i<dim;i++){A.bounds[i] = va_arg(ap,int);if(A.bounds[i]<0)return UNDERFLOW;elemtotal *=A.bounds[i];}va_end(ap);A.base = (ElemType*)malloc(elemtotal*sizeof(ElemType));if(!A.base)return ERROR;A.constants = (int*)malloc(dim*sizeof(int));if(!A.constants)return ERROR;A.constants[dim-1] = 1;for(i=dim-2;i>=0;i--)A.constants[i]= A.constants[i+1]*A.bounds[i+1];return OK;}void destroy_array(Array &A){if(A.base)free(A.base);if(A.bounds)free(A.bounds);if(A.constants)free(A.constants);A.base = A.bounds = A.constants = NULL;A.dim = 0;}Status locate(Array A,va_list ap,int &off){int i,idx ;off = 0;return OK;}Status value(ElemType &e,Array A,...){va_list ap;int i,off=0,idx;va_start(ap,A);for(i = 0;i<A.dim ;i++){idx = va_arg(ap,int);if(idx<0 || idx >=A.bounds[i])return ERROR;off += A.constants[i]*idx;}e = *(A.base+off);return OK;}Status assign(Array &A,ElemType e,...){va_list ap;int i,idx,off=0;va_start(ap,e);for(i = 0;i<A.dim ;i++){idx = va_arg(ap,int);if(idx<0 || idx >=A.bounds[i])return ERROR;off += A.constants[i]*idx;}*(A.base+off)=e;return OK;}
我们知道数组支持随机存储访问,那么对于数组结构,访问元素的形式才是需要关注的重点,对于一个n维的矩阵,每一维大小为b1,b2,...bn,那么如果给定索引j1,j2,...jn,那么要取得该元素,就需要求其在数组存储单元中的偏移量LOC[j1,j2,...jn]为
矩阵
矩阵是一个数学概念,但是它在计算机中的表现形式是基于二维数组的。这里我们主要关注稀疏矩阵,所谓稀疏矩阵是指在矩阵中非零元素较少,且分布没有规律。更为准确的描述是假设m×n的矩阵中,有t个元素不为零。令δ=t/(m×n),称δ为矩阵的稀疏因子,通常认为δ<=0.05时称为稀疏矩阵。
下面是基于三元组顺序表的稀疏矩阵压缩存储方式:
typedef int Status ;#define ERROR -1;#define OK 0;//稀疏矩阵的三元组顺序表存储结构#define MAX_SIZE 100 struct Triple{int i,j;//行、列索引ElemType e;};struct TSMatrix{Triple data[MAX_SIZE+1];//data[0]未用int mu,nu,tu;//行数、列数、非零元素数};Status create_matrix(TSMatrix &M){int i;Triple T;Status k;printf("请输入矩阵的行数、列数以及非零元素个数:");scanf("%d,%d,%d",&M.mu,&M.nu,&M.tu);if(M.tu>MAX_SIZE)return ERROR;M.data[0].i = 0;for(i=1;i<=M.tu;i++){do{printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:",i,M.mu,M.nu);scanf("%d,%d,%d",&T.i,&T.j,&T.e);k=0;if(T.i<1 || T.i>M.mu || T.j<1 || T.j>M.nu)k=1;if(T.i<M.data[i-1].i || T.i==M.data[i-1].i &&T.j<=M.data[i-1].j)k=1;}while(k);M.data[i]=T;}return OK;}int comp(int c1,int c2){if(c1<c2)return -1;if(c1==c2)return 0 ;return 1;}Status add_matrix(TSMatrix M,TSMatrix N,TSMatrix &Q){int m=1,n=1,q=0;if(M.mu!=N.mu || M.nu!=N.nu)return ERROR;Q.mu=M.mu;Q.nu=M.nu;while(m<=M.tu && n<=N.tu){switch(comp(M.data[m].i,N.data[n].i)){case -1:Q.data[++q]=M.data[m++];break;case 0:switch(comp(M.data[m].j,N.data[n].j)){case -1: Q.data[++q]=M.data[m++];break;case 0 :Q.data[++q]=M.data[m++];Q.data[q].e +=N.data[n++].e;if(Q.data[q].e==0)q--;break;case 1:Q.data[++q]=N.data[n++];break;}break;case 1:Q.data[++q]=N.data[n++];break;}}while(m<=M.tu)Q.data[++q]=M.data[m++];while(n<=N.tu)Q.data[++q]=N.data[n++];if(q>MAX_SIZE)return ERROR;Q.tu=q;return OK;}Status sub_matrix(TSMatrix M,TSMatrix N,TSMatrix &X){int i;if(M.mu!=N.mu || M.nu!=N.nu)return ERROR;for(i=1;i<=N.tu;++i)N.data[i].e*=-1;add_matrix(M,N,X);return OK;}//转置void transpose(TSMatrix M,TSMatrix &T){int p,col,q=1;T.mu = M.nu;T.nu = M.mu;T.tu = M.tu;if(T.tu){for(col=1;col<=M.nu;++col)for(p=1;p<=M.tu;++p)if(M.data[p].j==col){T.data[q].i=M.data[p].j;T.data[q].j=M.data[p].i;T.data[q++].e=M.data[p].e;}}}//快速转置Status fast_transpose(TSMatrix M,TSMatrix &T){int p,q;int col,t;T.mu = M.nu;T.nu = M.mu;T.tu = M.tu;int* num = (int*)malloc((M.nu+1)*sizeof(int));if(!num)return ERROR;int* cpot=(int*)malloc((M.nu+1)*sizeof(int));if(!cpot)return ERROR;if(T.tu){for(col=1;col<=M.nu;++col)num[col]=0;for(t=1;t<=M.tu;++t)++num[M.data[t].j];cpot[1]=1;for(col=2;col<=M.nu;++col)cpot[col]=cpot[col-1]+num[col-1];for(p=1;p<=M.tu;++p){col=M.data[p].j;q=cpot[col];T.data[q].i=M.data[p].j;T.data[q].j=M.data[p].i;T.data[q].e=M.data[p].e;++cpot[col];}}free(num);free(cpot);return OK;}void copy_matrix(TSMatrix M,TSMatrix &T){T=M;}void destroy_matrix(TSMatrix &M){M.mu=M.nu=M.tu = 0;}Status mult_matrix(TSMatrix M,TSMatrix N,TSMatrix &Q){int i,j,p,q;ElemType Qs;TSMatrix T;if(M.nu!=N.mu)return ERROR;Q.mu=M.mu;Q.nu=N.nu;Q.tu=0;transpose(N,T);for(i=1;i<=Q.mu;i++){q=1;for(j=1;j<=T.mu;j++){Qs=0;p=1;while(M.data[p].i<i)p++;while(T.data[q].i<j)q++;while(p<=M.tu && q<=T.tu&&M.data[p].i==i && T.data[q].i==j){switch(comp(M.data[p].j,T.data[q].j)){case -1:p++;break;case 0:Qs+=M.data[p++].e*T.data[q++].e;break;case 1:q++;break;}if(Qs){if(++Q.tu>MAX_SIZE)return ERROR;Q.data[Q.tu].i=i;Q.data[Q.tu].j=j;Q.data[Q.tu].e=Qs;}}}}return OK;}void print_matrix(TSMatrix M){int i,j,k=1;Triple *p=M.data+1;for(i=1;i<=M.mu;i++){for(j=1;j<=M.nu;j++){if(k<=M.tu && p->i==i &&p->j==j){printf("%3d",(p++)->e);k++;}else{printf("%3d",0);}}printf("\n");}}
这里,我们看看矩阵转置的操作。矩阵的转置是将矩阵中元素的行列位置进行互换。这里我们讨论稀疏矩阵的转置,对于一个矩阵A,如:
1 0 2 00 3 0 40 0 5 0其三元组的顺序表存储形式如下: i j e0 [0]1 1 1 [1]1 3 2 [2]2 2 3 [3]2 4 4 [4]3 3 5 [5]... ...mu=3,nu=4,tu=5这里需要注意的是,非零值按照一定的序列排序,转置过程需要保证非零元素的顺序,下面是矩阵转置的最简单的实现:
//将M转置transport(MAtrix M,MAtrix &X):begin:X.mu = M.nu;X.nu = M.mu;X.tu = M.tu;if 存在非零元素 for (i=1;i<M.nu;i++): do 对于每个非零元素eif e的列号为当前矩阵的行号将e的转置为X中的非零元素end
这个算法由于每次都要遍历每个非零元素,算法复杂度为O(nu*tu)。
考虑,转置的关键问题在于,将i,j进行调换后将元素放置到data中合适的位置,如果我们能预先知道每一列(T中每一行)中的第一个非零元素在data中的位置,那么在将元素做转置操作时,便可直接放到data中的合适位置上去,为了求取每一列中第一个非零元素的位置,需要先求得每一列非零元素的个数。这里定义两个向量num和cpot,num[col]表示矩阵中第col列中非零元的数目,cpot[col]表示M中第col列的第一个非零元在data中的恰当位置。显然有
cpot[1]=1;
cpot[col]=cpot[col-1]+num[col-1] 2<=col<=M.nu
快速转置的算法实现如下:
fast_transpose(Matrix M,Matrix &X)begin: X.mu=M.nu; X.nu=M.mu; X.tu=M.tu; if 存在非零元素for i=1->M.nu初始化num向量for j=1->M.tu求取每列中非零元素个数cpot[1]=1; for col=2->M.nu 求每列第一个非零元在data中的序号cpot向量 for p=1->M.tudo:取得非零元素的列号j;通过cpot 取得第j列的第一个非零元素在data中的序号qM.data[p].j ->X.data[q].iM.data[p].i->X.data[q].jM.data[p].e->X.data[q].e第j列的第一个非零元素在data中序号递增end
- BDS之数组与矩阵
- BDS之栈与队列
- 数组与矩阵---之字型打印矩阵
- BDS之链表
- BDS之串
- BDS
- BDS之线性顺序表
- matlab 数组与矩阵
- C#数组与矩阵
- 数组与矩阵
- Matlab数组与矩阵
- Python.Numpy学习零碎笔记之数组与矩阵
- UEFI Boot Flow 系列之 BDS Phase
- UEFI Boot Flow 系列之BDS
- BDS之链表经典问题
- BDS之串的模式匹配
- 数组与矩阵(1)_矩阵相乘
- 数组与矩阵---转圈打印矩阵
- File中几种方法的运用
- TOJ 3365 It's not Floyd Algorithm -- 强连通分量 + floyd
- requireJs
- 使用Hibernate过滤集合元素的两种方法
- Ubuntu12.04 安装lamp环境
- BDS之数组与矩阵
- 95 Android 文件存储(1)
- 大公司凭什么收购你?
- [c.y.j]搭建Spring、Spring MVC、Mybatis和Freemarker
- Info.plist与Prefix.pch修改文件位置遇到的问题及解决方法
- ACM-最小生成树之Highways——poj2485
- 目前主要是做的iOS前端开发,想要学习了解后台的开发。请问需要从何入手 需要学习哪方面技术?
- opencv中 MSER 源码赏析
- C语言中类型转换时的数据丢失问题