数据结构伪C代码:5.数组和广义表

来源:互联网 发布:我的世界手机js制作器 编辑:程序博客网 时间:2024/05/17 22:18
//------------数组的顺序存储表示------------#include<stdarg.h>#define MAX_ARRAY_DIM 8  //假设数组维数的最大值为8typedef 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   //假设非零元个数的最大值为12500typedef struct{   int i,j;   ElemType w;}Triple;typedef struct{  Triple data[MAXSIZE+1];  //非零元三元组表,data[9]未用  int mu,nu,tu;           //矩阵的行数,列数和非零元个数}TSMatrix;//算法5.1status 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.2status 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.3status 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.4status 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.6status 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 函数severstatus 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);   }}

0 0