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

//------------数组的顺序存储表示------------
#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);
	   	}
	}

你可能感兴趣的:(数据结构,算法,typedef,递归算法)