//------------数组的顺序存储表示------------ #include<stdarg.h> #define MAX_ARRAY_DIM 8 //假设数组维数的最大值为8 typedef struct{ ElemType *base; //数组元素基址,由InitArray分配 int dim; //数组维数 int *bounds; //数组维界基址,由InitArray分配 int *constants; //数组映像函数常量基址,由InitArray分配 }Array; //=============基本操作函数=================== status InitArray(Array &A,int dim,...){ //若维数dim和各维长度合法,则构造相应的数组A,并返回OK if(dim<1||dim>MAX_ARRAY_DIM) return ERROR; A.dim=dim; A.bounds=(int *)malloc(dim *sizeof(int)); if(!A.bounds) return(OVERFLOW); //若各维长度合法,则存入A.bounds,并求出A的元素总数elemtotal elemtotal=1; va_start(ap,dim); //ap为va_liat类型,是存放变长参数表信息的数组 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) exit(OVERFLOW); //求映像函数的常数ci,并存入A.constants[i-1],i=1,...dim A.constants=(int *)malloc(dim *sizeof(int)); if(!A.constants) exit(OVERFLOW); A.constants[dim-1]=1; //L=1,指针的增减以元素的大小为单位 for(i=dim-2;i>=0;i--) A.constants[i]=A.bounds[i+1]*A.constants[i+1]; return ok; } status DestroyArray(Array &A){ //销毁数组A if(!A.base) return Error; free(A.base); A.base=NULL; if(!A.bounds) return Error; free(A.bounds) A.bounds=NULL; if(!A.constants) return Error; free(A.constants); A.constants=NULL; return ok; } status Locate(Array A,va_list ap,int &off){ //若ap指示的各下标值合法,则求出该元素在A中相对地址off off=0; for(i=0;i<A.dim;i++){ ind=va_arg(ap,int); if(ind<0||ind>=A.bounds[i]) return OVERFLOW; off+=A.countants[i]*ind; } return ok; } status Value(Array A,ElemType &e,...){ //A是n维数组,e为元素变量,随后是n个下标值 //若各下标不超界,则e赋值为所指定的A的元素值,并返回ok va_start(ap,e); if((result=Locate(A,ap,off))<=0) return result; e=*(A.base+off); return ok; } status Assign(Array &A,ElemType e,...){ //A是n维数组,e为元素变量,随后是n个下标值 //若下标不超界,则将e的值赋值给所指定的A的元素,并返回ok va_start(ap,e); if((result=Locate(A,ap,off))<=0) return result; *(A.base+off)=e; return ok; } //---------------稀疏矩阵的三元组顺序表存储表示------------- #define MAXSIZE 12500 //假设非零元个数的最大值为12500 typedef struct{ int i,j; ElemType w; }Triple; typedef struct{ Triple data[MAXSIZE+1]; //非零元三元组表,data[9]未用 int mu,nu,tu; //矩阵的行数,列数和非零元个数 }TSMatrix; //算法5.1 status TransposeSMatrix(TSMatrix M,TSMstrix &T){ //采用三元组表存储表示,求稀疏矩阵M的转置矩阵T T.mu=M.mu; T.nu=M.nu; T.tu=M.tu; if(T.tu){ q=1; for(col=1;col<=M.mu;col++) for(p=1;p<=M.nu;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; q++; } } return ok; } //算法5.2 status FastTransposeSMatrix(TSMatrix M,TSMatrix &T){ //采用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T T.mu=M.mu; T.nu=M.nu; T.tu=M.tu; 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]++; //求M中每一列含非零元个数 cpot[1]=1; //求第col列中第一个非零元在b.data中的序号 for(col=2;col<=M.tu;p++) 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]++; } } return ok; } //============================================ typedef struct{ Triple data[MAXSIZE+1]; //非零元三元组表 int rpos[MAXRC+1]; //各行第一个非零元的位置表 int mu,nu,tu; //矩阵的行数、列数和非零元个数 }RLSMatrix; //------------------------ Q初始化; if(Q是非零矩阵){ //逐行求积 for(row=1;arow<=M.mu;arow++){ //处理M的每一行 ctemp[]=0; //累加器清零 计算Q中第arow行的积并存入ctemp[]中; 将ctemp[]中非零元压缩存储到Q.data; } } //算法5.3 status MultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q){ //求矩阵乘积Q=M*N,采用行逻辑连接存储表示 if(M.nu!=N.mu) return error; Q.mu=M.mu; Q.nu=N.nu; Q.tu=0; if(M.tu*N.tu!=0){ for(arow=1;arow<=M.mu;arow++){ ctemp[]=0; Q.rpos[arow]=Q.tu+1; if(arow<M.mu) tp=M.rpos[arow+1]; else tp=M.tu+1; for(p=M.rpos[arow];p<tp;p++){ brow=M.data[p].j; if(brow<N.mu) t=N.rpos[brow+1]; else t=N.tu+1; for(q=N.rops[brow];q<t;q++){ ccol=N.data[q].j; ctemp[ccol]+=M.data[p].e*N.data[q].e; } } for(ccol=1;ccol<=Q.nu;ccol++) if(ctemp[ccol]){ if(++Q.tu>MAXSIZE) return error; Q.data[Q.tu]=(arow,ccol,ctemp[ccol]); } } } return ok; } //-----------------稀疏矩阵的十字链表存储表示------------------ typedef struct OLNode{ int i,j; //该非零元的行和列的坐标 ElemType e; struct OLNode *right,*down;//该非零元所在行表和列表的后继链表 }OLNode,*OLink; typedef struct{ OLink *rhead,*chead; //行和列链表头指针向量基址由CreateSMatrix分配 int mu,nu,tu; //行数。列数和非零元个数 }CrossList; //算法5.4 status CreateSMatrix_OL(CrossList &M){ //创建稀疏矩阵M;采用十字链表存储表示 if(M) free(M); scanf(&m,&n,&t); //输入M的行数,列数,非零元个数 M.mu:=m; M.nu:=n; M.tu:=t; if(!(M.rhead=(OLink *)malloc((m+1)*sizeof(OLink)))) exit(overflow); if(!(M.chead=(OLink *)malloc((n+1)*sizeof(OLink)))) exit(overflow); M.rhead[]=M.chead[]=NULL; //初始化行列头指针向量;各行列链表为空链表 for(scanf(&i,&j,&e);i!=0;scanf(&i,&j,&e)){ //按任意次序输入非零元 if(!(p=(OLNode *)malloc(sizeof(OLNode)))) exit(overflow); //生成结点 p->i=i; p->j=j; p->e=e; if(M.rhead[i]==NULL||M.rhead[i]->j>j){ p->right=M.rhead[i]; M.rhead[i]=p; } else{ for(q=M.rhead[i];(q->right)&&q->right->j<j;q=q->right); p->right=q->right; q->right=p; } if(M.chead[j]==NULL||M.chead[j]->i>i){ p->down=M.chead[j]; M.chead[j]->down=p; } else{ for(q=M.chead[j];(q->down)&&q->down->i<i;q=q->down); p->down=q->down; q->down=p; } } return ok; } //----------------------广义表的头尾链表存储表示-------------------------------- typedef enum{ATOM,LIST}ElemTag; //ATOM==0:原子,LIST==1:子表 typedef struct GLNode{ ElemTag tag; //公共部分,用于区分原子结点和表结点 union{ //原子结点和表结点的联合部分 AtomType atom; struct{ struct GLNode *hp,*tp; }ptr; //ptr是表结点的指针域,ptr.hp和ptr.tp分别指向表头和表尾 } }*GList; //广义表类型 //----------------------广义表的扩展线性链表存储表示-------------------------------- typedef enum{ATOM,LIST}ElemTag; //ATOM==0:原子,LIST==1:子表 typedef struct GLNode{ ElemTag tag; //公共部分,用于区分原子结点和表结点 union{ //原子结点和表结点的联合部分 AtomType atom; //原子结点的值域 struct GLNode *hp; //表结点的表头指针 }; struct GLNode *tp; //相当于线性链表的next,指向下一个元素结点 }*GList; //广义表类型GList是一种扩展的线性链表 //----------------------m元多项式的广义表的存储结构----------------- typedef struct MPNode{ ElemTag tag; //区分原子结点和表结点 int exp; //指数域 union{ float coef; //系数域 struct MPNode *hp; //表结点的表头指针 }; struct MPNode *tp; //相当于线性链表的next,指向下一个元素结点 }*MPList; //m元多项式广义表类型 //算法5.5 求广义表深度的递归算法 int GListDepth(Glist L){ //采用头尾链表存储结构,求广义表L的深度 if(!L) return 1; //空表深度为1 if(L->tag==ATOM) return 0; //原子深度为0 for(max=0,pp=L;pp;pp=pp->ptr.tp){ dep=GListDepth(pp->ptr.hp); //求以pp->ptr.hp为头指针的字表深度 if(dep>max) max=dep; } return max+1; //非空表的深度是各元素的深度的最大值加1 } //算法5.6 status CopyGList(GList &T,GList L){ //采用头尾链表存储结构,由广义表L复制得到广义表T if(!L) T=NULL; //复制空表 else{ if(!(T=(GList)malloc(sizeof(GLNode)))) //建立结点 exit(overflow); T->tag=L->tag; if(L->tag==ATOM) T->atom=L->atom; //复制单原子 else{ CopyGList(T->ptr.hp,L->ptr.hp); //复制广义表L->ptr.hp的一个副本T->ptr.hp CopyGList(T->ptr.tp,l->ptr.tp); //复制广义表L->ptr.tp的一个副本T->ptr.tp } } return ok; } //算法5.7 建广义表存储结构的递归算法 status CreateGList(GList &L,SString S){ //采用头尾链表存储结构,由广义表的书写形式串S创建广义表L。设emp="()" if(StrCompare(S,emp)) L=NULL; //创建空表 else{ if(!(L=(GList)malloc(sizeof(GLNode)))) exit(overflow); //建表结点 if(StrLength(S)==1){ //创建单原子广义表 L->tag=ATOM; L->atom=S; } else{ L->tag=LIST; p=L; SubString(S)(sub,S,2,StrLength(S)-2); //托外层括号 do{ //重复建n个字表 sever(sub,hsub); //从sub中分离出表头串hsub CreateGList(p->ptr.hp,hsub); q=p; if(!StrEmpty(sub)){ //表尾不空 if(!(p=(GLNode *)malloc(sizeof(GLNode)))) exit(overflow); p->tag=LIST; q->ptr.tp=p; } }while(!StrEmpty(sub)); q->ptr.tp=NULL: } } return ok; } //算法5.8 函数sever status sever(SString &str,SString &hstr){ //将非空串str分割成两部分:hstr为第一个‘,’,之前的子串,str为之后的子串 n=StrLength(str); i=0; k=0; //k记尚未配对的左括号个数 do{ //搜索最外层的第一个逗号 i++; SubString(ch,str,i,1); if(ch=='(') k++; else if(ch==')') k--; }while(i<n&&(ch!=','||k!=)); if(i<n){ SubString(hstr,str,1,i-1); SubString(str,str,i+1,n-i); } else{ StrCopy(hstr,str); ClearString(str); } }