func5-1.cpp && bo5-1~bo5-6.cpp s 数组和广义表 算法

 
  1.  // func5-1.cpp 广义表的书写形式串为SString类型,包括算法5.8。bo5-5.cpp和bo5-6.cpp调用
  2.  #include"c4-1.h" // 定义SString类型
  3.  #include"bo4-1.cpp" // SString类型的基本操作
  4.  void sever(SString str,SString hstr) // 算法5.8改。SString是数组,不需引用类型
  5.  { // 将非空串str分割成两部分:hstr为第一个','之前的子串,str为之后的子串
  6.    int n,k,i; // k记尚未配对的左括号个数
  7.    SString ch,c1,c2,c3;
  8.    n=StrLength(str); // n为串str的长度
  9.    StrAssign(c1,","); // c1=','
  10.    StrAssign(c2,"("); // c2='('
  11.    StrAssign(c3,")"); // c3=')'
  12.    SubString(ch,str,1,1); // ch为串str的第1个字符
  13.    for(i=1,k=0;i<=n&&StrCompare(ch,c1)||k!=0;++i) // i小于串长且ch不是','
  14.    { // 搜索最外层的第一个逗号
  15.      SubString(ch,str,i,1); // ch为串str的第i个字符
  16.      if(!StrCompare(ch,c2)) // ch='('
  17.        ++k; // 左括号个数+1
  18.      else if(!StrCompare(ch,c3)) // ch=')'
  19.        --k; // 左括号个数-1
  20.    }
  21.    if(i<=n) // 串str中存在',',它是第i-1个字符
  22.    {
  23.      SubString(hstr,str,1,i-2); // hstr返回串str','前的字符
  24.      SubString(str,str,i,n-i+1); // str返回串str','后的字符
  25.    }
  26.    else // 串str中不存在','
  27.    {
  28.      StrCopy(hstr,str); // 串hstr就是串str
  29.      ClearString(str); // ','后面是空串
  30.    }
  31.  }
  1.  // bo5-1.cpp 顺序存储数组(存储结构由c5-1.h定义)的基本操作(5个)
  2.  Status InitArray(Array &A,int dim,...)
  3.  { // 若维数dim和各维长度合法,则构造相应的数组A,并返回OK
  4.    int elemtotal=1,i; // elemtotal是数组元素总数,初值为1(累乘器)
  5.    va_list ap;
  6.    if(dim<1||dim>MAX_ARRAY_DIM)
  7.      return ERROR;
  8.    A.dim=dim;
  9.    A.bounds=(int *)malloc(dim*sizeof(int));
  10.    if(!A.bounds)
  11.      exit(OVERFLOW);
  12.    va_start(ap,dim);
  13.    for(i=0;i<dim;++i)
  14.    {
  15.      A.bounds[i]=va_arg(ap,int);
  16.      if(A.bounds[i]<0)
  17.        return UNDERFLOW; // 在math.h中定义为4
  18.      elemtotal*=A.bounds[i];
  19.    }
  20.    va_end(ap);
  21.    A.base=(ElemType *)malloc(elemtotal*sizeof(ElemType));
  22.    if(!A.base)
  23.      exit(OVERFLOW);
  24.    A.constants=(int *)malloc(dim*sizeof(int));
  25.    if(!A.constants)
  26.      exit(OVERFLOW);
  27.    A.constants[dim-1]=1;
  28.    for(i=dim-2;i>=0;--i)
  29.      A.constants[i]=A.bounds[i+1]*A.constants[i+1];
  30.    return OK;
  31.  }
  32.  void DestroyArray(Array &A)
  33.  { // 销毁数组A
  34.    if(A.base)
  35.      free(A.base);
  36.    if(A.bounds)
  37.      free(A.bounds);
  38.    if(A.constants)
  39.      free(A.constants);
  40.    A.base= A.bounds=A.constants=NULL;
  41.    A.dim=0;
  42.  }
  43.  Status Locate(Array A,va_list ap,int &off) // Value()、Assign()调用此函数
  44.  { // 若ap指示的各下标值合法,则求出该元素在A中的相对地址off
  45.    int i,ind;
  46.    off=0;
  47.    for(i=0;i<A.dim;i++)
  48.    {
  49.      ind=va_arg(ap,int);
  50.      if(ind<0||ind>=A.bounds[i])
  51.        return OVERFLOW;
  52.      off+=A.constants[i]*ind;
  53.    }
  54.    return OK;
  55.  }
  56.  Status Value(ElemType &e,Array A,...) // 在VC++中,...之前的形参不能是引用类型
  57.  { // ...依次为各维的下标值,若各下标合法,则e被赋值为A的相应的元素值
  58.    va_list ap;
  59.    int off;
  60.    va_start(ap,A);
  61.    if(Locate(A,ap,off)==OVERFLOW) // 调用Locate()
  62.      return ERROR;
  63.    e=*(A.base+off);
  64.    return OK;
  65.  }
  66.  Status Assign(Array A,ElemType e,...) // 变量A的值不变,故不需要&
  67.  { // ...依次为各维的下标值,若各下标合法,则将e的值赋给A的指定的元素
  68.    va_list ap;
  69.    int off;
  70.    va_start(ap,e);
  71.    if(Locate(A,ap,off)==OVERFLOW) // 调用Locate()
  72.      return ERROR;
  73.    *(A.base+off)=e;
  74.    return OK;
  75.  }
  1.  // bo5-2.cpp 三元组稀疏矩阵的基本操作(8个),包括算法5.1
  2.  Status CreateSMatrix(TSMatrix &M)
  3.  { // 创建稀疏矩阵M
  4.    int i,m,n;
  5.    ElemType e;
  6.    Status k;
  7.    printf("请输入矩阵的行数,列数,非零元素数:");
  8.    scanf("%d,%d,%d",&M.mu,&M.nu,&M.tu);
  9.    if(M.tu>MAX_SIZE)
  10.      return ERROR;
  11.    M.data[0].i=0; // 为以下比较顺序做准备
  12.    for(i=1;i<=M.tu;i++)
  13.    {
  14.      do
  15.      {
  16.        printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:",i,M.mu,M.nu);
  17.        scanf("%d,%d,%d",&m,&n,&e);
  18.        k=0;
  19.        if(m<1||m>M.mu||n<1||n>M.nu) // 行或列超出范围
  20.          k=1;
  21.        if(m<M.data[i-1].i||m==M.data[i-1].i&&n<=M.data[i-1].j) // 行或列的顺序有错
  22.          k=1;
  23.      }while(k);
  24.      M.data[i].i=m;
  25.      M.data[i].j=n;
  26.      M.data[i].e=e;
  27.    }
  28.   return OK;
  29.  }
  30.  void DestroySMatrix(TSMatrix &M)
  31.  { // 销毁稀疏矩阵M
  32.    M.mu=M.nu=M.tu=0;
  33.  }
  34.  void PrintSMatrix(TSMatrix M)
  35.  { // 输出稀疏矩阵M
  36.    int i;
  37.    printf("%d行%d列%d个非零元素。/n",M.mu,M.nu,M.tu);
  38.    printf("行  列  元素值/n");
  39.    for(i=1;i<=M.tu;i++)
  40.      printf("%2d%4d%8d/n",M.data[i].i,M.data[i].j,M.data[i].e);
  41.  }
  42.  void PrintSMatrix1(TSMatrix M)
  43.  { // 按矩阵形式输出M
  44.    int i,j,k=1;
  45.    Triple *p=M.data;
  46.    p++; // p指向第1个非零元素
  47.    for(i=1;i<=M.mu;i++)
  48.    {
  49.      for(j=1;j<=M.nu;j++)
  50.        if(k<=M.tu&&p->i==i&&p->j==j) // p指向非零元,且p所指元素为当前处理元素
  51.        {
  52.          printf("%3d",p->e); // 输出p所指元素的值
  53.          p++; // p指向下一个元素
  54.          k++; // 计数器+1
  55.        }
  56.        else // p所指元素不是当前处理元素
  57.          printf("%3d",0); // 输出0
  58.      printf("/n");
  59.    }
  60.  }
  61.  void CopySMatrix(TSMatrix M,TSMatrix &T)
  62.  { // 由稀疏矩阵M复制得到T
  63.    T=M;
  64.  }
  65.  int comp(int c1,int c2)
  66.  { // AddSMatrix函数要用到,另加
  67.    if(c1<c2)
  68.      return -1;
  69.    if(c1==c2)
  70.      return 0;
  71.    return 1;
  72.  }
  73.  Status AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
  74.  { // 求稀疏矩阵的和Q=M+N
  75.    int m=1,n=1,q=0;
  76.    if(M.mu!=N.mu||M.nu!=N.nu) // M、N两稀疏矩阵行或列数不同
  77.      return ERROR;
  78.    Q.mu=M.mu;
  79.    Q.nu=M.nu;
  80.    while(m<=M.tu&&n<=N.tu) // 矩阵M和N的元素都没处理完
  81.    {
  82.      switch(comp(M.data[m].i,N.data[n].i))
  83.      {
  84.        case -1: Q.data[++q]=M.data[m++]; // 将矩阵M的当前元素值赋给矩阵Q
  85.         break;
  86.        case  0: switch(comp(M.data[m].j,N.data[n].j)) // M、N矩阵当前元素的行相等,继续比较列
  87.                 {
  88.                   case -1: Q.data[++q]=M.data[m++];
  89.                            break;
  90.                   case  0: Q.data[++q]=M.data[m++]; // M、N矩阵当前非零元素的行列均相等
  91.                            Q.data[q].e+=N.data[n++].e; // 矩阵M、N的当前元素值求和并赋给矩阵Q
  92.                            if(Q.data[q].e==0) // 元素值为0,不存入压缩矩阵
  93.                              q--;
  94.                            break;
  95.                   case  1: Q.data[++q]=N.data[n++];
  96.                 }
  97.                 break;
  98.        case  1: Q.data[++q]=N.data[n++]; // 将矩阵N的当前元素值赋给矩阵Q
  99.      }
  100.    }
  101.    while(m<=M.tu) // 矩阵N的元素全部处理完毕
  102.      Q.data[++q]=M.data[m++];
  103.    while(n<=N.tu) // 矩阵M的元素全部处理完毕
  104.      Q.data[++q]=N.data[n++];
  105.    Q.tu=q; // 矩阵Q的非零元素个数
  106.    if(q>MAX_SIZE) // 非零元素个数太多
  107.      return ERROR;
  108.    return OK;
  109.  }
  110.  Status SubtSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
  111.  { // 求稀疏矩阵的差Q=M-N
  112.    int i;
  113.    for(i=1;i<=N.tu;i++)
  114.      N.data[i].e*=-1;
  115.    return AddSMatrix(M,N,Q);
  116.  }
  117.  void TransposeSMatrix(TSMatrix M,TSMatrix &T)
  118.  { // 求稀疏矩阵M的转置矩阵T。算法5.1改
  119.    int p,q,col;
  120.    T.mu=M.nu;
  121.    T.nu=M.mu;
  122.    T.tu=M.tu;
  123.    if(T.tu)
  124.    {
  125.      q=1;
  126.      for(col=1;col<=M.nu;++col)
  127.        for(p=1;p<=M.tu;++p)
  128.          if(M.data[p].j==col)
  129.          {
  130.            T.data[q].i=M.data[p].j;
  131.            T.data[q].j=M.data[p].i;
  132.            T.data[q].e=M.data[p].e;
  133.            ++q;
  134.          }
  135.    }
  136.  }
  137.  Status MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
  138.  { // 求稀疏矩阵的乘积Q=M×N
  139.    int i,j;
  140.    ElemType *Nc,*Tc;
  141.    TSMatrix T; // 临时矩阵
  142.    if(M.nu!=N.mu)
  143.      return ERROR;
  144.    T.nu=M.mu; // 临时矩阵T是Q的转秩矩阵
  145.    T.mu=N.nu;
  146.    T.tu=0;
  147.    Nc=(ElemType*)malloc((N.mu+1)*sizeof(ElemType)); // Nc为矩阵N一列的临时数组(非压缩,[0]不用)
  148.    Tc=(ElemType*)malloc((M.nu+1)*sizeof(ElemType)); // Tc为矩阵T一行的临时数组(非压缩,[0]不用)
  149.    if(!Nc||!Tc) // 创建临时数组不成功
  150.      exit(ERROR);
  151.    for(i=1;i<=N.nu;i++) // 对于N的每一列
  152.    {
  153.      for(j=1;j<=N.mu;j++)
  154.        Nc[j]=0; // 矩阵Nc的初值为0
  155.      for(j=1;j<=M.mu;j++)
  156.        Tc[j]=0; // 临时数组Tc的初值为0,[0]不用
  157.      for(j=1;j<=N.tu;j++) // 对于N的每一个非零元素
  158.        if(N.data[j].j==i) // 属于第i列
  159.      Nc[N.data[j].i]=N.data[j].e; // 根据其所在行将其元素值赋给相应的Nc
  160.      for(j=1;j<=M.tu;j++) // 对于M的每一个值
  161.        Tc[M.data[j].i]+=M.data[j].e*Nc[M.data[j].j]; // Tc中存N的第i列与M相乘的结果
  162.      for(j=1;j<=M.mu;j++)
  163.        if(Tc[j]!=0)
  164.        {
  165.          T.data[++T.tu].e=Tc[j];
  166.          T.data[T.tu].i=i;
  167.          T.data[T.tu].j=j;
  168.        }
  169.    }
  170.    if(T.tu>MAX_SIZE) // 非零元素个数太多
  171.      return ERROR;
  172.    TransposeSMatrix(T,Q); // 将T的转秩赋给Q
  173.    DestroySMatrix(T); // 销毁临时矩阵T
  174.    free(Tc); // 释放动态数组Tc和Nc
  175.    free(Nc);
  176.    return OK;
  177.  }
  1.  // bo5-3.cpp 行逻辑链接稀疏矩阵(存储结构由c5-3.h定义)的基本操作(8个),包括算法5.3
  2.  Status CreateSMatrix(RLSMatrix &M)
  3.  { // 创建稀疏矩阵M
  4.    int i,j;
  5.    Triple T;
  6.    Status k;
  7.    printf("请输入矩阵的行数,列数,非零元素数:");
  8.    scanf("%d,%d,%d",&M.mu,&M.nu,&M.tu);
  9.    if(M.tu>MAX_SIZE||M.mu>MAX_RC)
  10.      return ERROR;
  11.    M.data[0].i=0; // 为以下比较做准备
  12.    for(i=1;i<=M.tu;i++)
  13.    {
  14.      do
  15.      {
  16.        printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:",i,M.mu,M.nu);
  17.        scanf("%d,%d,%d",&T.i,&T.j,&T.e);
  18.        k=0;
  19.        if(T.i<1||T.i>M.mu||T.j<1||T.j>M.nu) // 行、列超出范围
  20.          k=1;
  21.        if(T.i<M.data[i-1].i||T.i==M.data[i-1].i&&T.j<=M.data[i-1].j) // 没有按顺序输入非零元素
  22.          k=1;
  23.      }while(k); // 当输入有误,重新输入
  24.      M.data[i]=T;
  25.    }
  26.    for(i=1;i<=M.mu;i++) // 给rpos[]赋初值0
  27.      M.rpos[i]=0;
  28.    for(i=1;i<=M.tu;i++) // 计算每行非零元素数并赋给rpos[]
  29.      M.rpos[M.data[i].i]++;
  30.    for(i=M.mu;i>=1;i--) // 计算rpos[]
  31.    {
  32.      M.rpos[i]=1; // 赋初值1
  33.      for(j=i-1;j>=1;j--)
  34.        M.rpos[i]+=M.rpos[j];
  35.    }
  36.    return OK;
  37.  }
  38.  void DestroySMatrix(RLSMatrix &M)
  39.  { // 销毁稀疏矩阵M(使M为0行0列0个非零元素的矩阵)
  40.    M.mu=M.nu=M.tu=0;
  41.  }
  42.  void PrintSMatrix(RLSMatrix M)
  43.  { // 输出稀疏矩阵M
  44.    int i;
  45.    printf("%d行%d列%d个非零元素。/n",M.mu,M.nu,M.tu);
  46.    printf("行  列  元素值/n");
  47.    for(i=1;i<=M.tu;i++)
  48.      printf("%2d%4d%8d/n",M.data[i].i,M.data[i].j,M.data[i].e);
  49.    for(i=1;i<=M.mu;i++)
  50.      printf("第%d行的第一个非零元素是本矩阵第%d个元素/n",i,M.rpos[i]);
  51.  }
  52.  void PrintSMatrix1(RLSMatrix M)
  53.  { // 按矩阵形式输出M
  54.    int i,j,k=1;
  55.    Triple *p=M.data;
  56.    p++; // p指向第1个非零元素
  57.    for(i=1;i<=M.mu;i++)
  58.    {
  59.      for(j=1;j<=M.nu;j++)
  60.        if(k<=M.tu&&p->i==i&&p->j==j) // p指向非零元,且p所指元素为当前处理元素
  61.        {
  62.          printf("%3d",p->e); // 输出p所指元素的值
  63.          p++; // p指向下一个元素
  64.          k++; // 计数器+1
  65.        }
  66.        else // p所指元素不是当前处理元素
  67.          printf("%3d",0); // 输出0
  68.      printf("/n");
  69.    }
  70.  }
  71.  void CopySMatrix(RLSMatrix M,RLSMatrix &T)
  72.  { // 由稀疏矩阵M复制得到T
  73.    T=M;
  74.  }
  75.  Status AddSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q)
  76.  { // 求稀疏矩阵的和Q=M+N
  77.    int k,p,q,tm,tn;
  78.    if(M.mu!=N.mu||M.nu!=N.nu)
  79.      return ERROR;
  80.    Q.mu=M.mu; // Q矩阵行数
  81.    Q.nu=M.nu; // Q矩阵列数
  82.    Q.tu=0; // Q矩阵非零元素数初值
  83.    for(k=1;k<=M.mu;++k) // 对于每一行,k指示行号
  84.    {
  85.      Q.rpos[k]=Q.tu+1; // Q矩阵第k行的第1个元素的位置
  86.      p=M.rpos[k]; // p指示M矩阵第k行当前元素的序号
  87.      q=N.rpos[k]; // q指示N矩阵第k行当前元素的序号
  88.      if(k==M.mu) // 是最后一行
  89.      {
  90.        tm=M.tu+1; // tm,tn分别是p,q的上界
  91.        tn=N.tu+1;
  92.      }
  93.      else
  94.      {
  95.        tm=M.rpos[k+1];
  96.        tn=N.rpos[k+1];
  97.      }
  98.      while(p<tm&&q<tn) // M,N矩阵均有第k行元素未处理
  99.        if(M.data[p].j==N.data[q].j) // M矩阵当前元素的列=N矩阵当前元素的列
  100.        {
  101.      if(M.data[p].e+N.data[q].e!=0) // 和不为0,存入Q
  102.      {
  103.        Q.data[++Q.tu]=M.data[p];
  104.        Q.data[Q.tu].e+=N.data[q].e;
  105.      }
  106.      p++;
  107.      q++;
  108.        }
  109.        else if(M.data[p].j<N.data[q].j) // M矩阵当前元素的列<N矩阵当前元素的列
  110.      Q.data[++Q.tu]=M.data[p++]; // 将M的当前值赋给Q
  111.        else // M矩阵当前元素的列>N矩阵当前元素的列
  112.          Q.data[++Q.tu]=N.data[q++]; // 将N的当前值赋给Q
  113.      while(p<tm) // M矩阵还有第k行的元素未处理
  114.        Q.data[++Q.tu]=M.data[p++]; // 将M的当前值赋给Q
  115.      while(q<tn) // N矩阵还有k行的元素未处理
  116.        Q.data[++Q.tu]=N.data[q++]; // 将N的当前值赋给Q
  117.    }
  118.    if(Q.tu>MAX_SIZE)
  119.      return ERROR;
  120.    else
  121.      return OK;
  122.  }
  123.  Status SubtSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q)
  124.  { // 求稀疏矩阵的差Q=M-N
  125.    int i;
  126.    if(M.mu!=N.mu||M.nu!=N.nu)
  127.      return ERROR;
  128.    for(i=1;i<=N.tu;++i) // 对于N的每一元素,其值乘以-1
  129.      N.data[i].e*=-1;
  130.    AddSMatrix(M,N,Q); // Q=M+(-N)
  131.    return OK;
  132.  }
  133.  Status MultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q)
  134.  { // 求稀疏矩阵乘积Q=M×N。算法5.3改
  135.    int arow,brow,p,q,ccol,ctemp[MAX_RC+1],t,tp;
  136.    if(M.nu!=N.mu) // 矩阵M的列数应和矩阵N的行数相等
  137.      return ERROR;
  138.    Q.mu=M.mu; // Q初始化
  139.    Q.nu=N.nu;
  140.    Q.tu=0;
  141.    if(M.tu*N.tu==0) // M和N至少有一个是零矩阵
  142.      return ERROR;
  143.    for(arow=1;arow<=M.mu;++arow)
  144.    { // 从M的第一行开始,到最后一行,arow是M的当前行
  145.      for(ccol=1;ccol<=Q.nu;++ccol)
  146.        ctemp[ccol]=0; // Q的当前行的各列元素累加器清零
  147.      Q.rpos[arow]=Q.tu+1; // Q当前行的第1个元素位于上1行最后1个元素之后
  148.      if(arow<M.mu)
  149.        tp=M.rpos[arow+1];
  150.      else
  151.        tp=M.tu+1; // 给最后1行设界
  152.      for(p=M.rpos[arow];p<tp;++p)
  153.      { // 对M当前行中每一个非零元
  154.        brow=M.data[p].j; // 找到对应元在N中的行号(M当前元的列号)
  155.        if(brow<N.mu)
  156.          t=N.rpos[brow+1];
  157.        else
  158.          t=N.tu+1; // 给最后1行设界
  159.        for(q=N.rpos[brow];q<t;++q)
  160.        {
  161.          ccol=N.data[q].j; // 乘积元素在Q中列号
  162.          ctemp[ccol]+=M.data[p].e*N.data[q].e;
  163.        }
  164.      } // 求得Q中第arow行的非零元
  165.      for(ccol=1;ccol<=Q.nu;++ccol) // 压缩存储该行非零元
  166.        if(ctemp[ccol]!=0)
  167.        {
  168.          if(++Q.tu>MAX_SIZE)
  169.            return ERROR;
  170.          Q.data[Q.tu].i=arow;
  171.          Q.data[Q.tu].j=ccol;
  172.          Q.data[Q.tu].e=ctemp[ccol];
  173.        }
  174.    }
  175.    return OK;
  176.  }
  177.  void TransposeSMatrix(RLSMatrix M,RLSMatrix &T)
  178.  { // 求稀疏矩阵M的转置矩阵T
  179.    int p,q,t,col,*num;
  180.    num=(int *)malloc((M.nu+1)*sizeof(int));
  181.    T.mu=M.nu;
  182.    T.nu=M.mu;
  183.    T.tu=M.tu;
  184.    if(T.tu)
  185.    {
  186.      for(col=1;col<=M.nu;++col)
  187.        num[col]=0;  // 设初值
  188.      for(t=1;t<=M.tu;++t) // 求M中每一列非零元个数
  189.        ++num[M.data[t].j];
  190.      T.rpos[1]=1;
  191.      for(col=2;col<=M.nu;++col) // 求M中第col中第一个非零元在T.data中的序号
  192.        T.rpos[col]=T.rpos[col-1]+num[col-1];
  193.      for(col=1;col<=M.nu;++col)
  194.        num[col]=T.rpos[col];
  195.      for(p=1;p<=M.tu;++p)
  196.      {
  197.        col=M.data[p].j;
  198.        q=num[col];
  199.        T.data[q].i=M.data[p].j;
  200.        T.data[q].j=M.data[p].i;
  201.        T.data[q].e=M.data[p].e;
  202.        ++num[col];
  203.      }
  204.    }
  205.    free(num);
  206.  }
  1.  // bo5-4.cpp 稀疏矩阵的十字链表存储(存储结构由c5-4.h定义)的基本操作(9个),包括算法5.4
  2.  void InitSMatrix(CrossList &M)
  3.  { // 初始化M(CrossList类型的变量必须初始化,否则创建、复制矩阵将出错)。加
  4.    M.rhead=M.chead=NULL;
  5.    M.mu=M.nu=M.tu=0;
  6.  }
  7.  void InitSMatrixList(CrossList &M)
  8.  { // 初始化十字链表表头指针向量。加
  9.    int i;
  10.    if(!(M.rhead=(OLink*)malloc((M.mu+1)*sizeof(OLink)))) // 生成行表头指针向量
  11.      exit(OVERFLOW);
  12.    if(!(M.chead=(OLink*)malloc((M.nu+1)*sizeof(OLink)))) // 生成列表头指针向量
  13.      exit(OVERFLOW);
  14.    for(i=1;i<=M.mu;i++) // 初始化矩阵T的行表头指针向量,各行链表为空
  15.      M.rhead[i]=NULL;
  16.    for(i=1;i<=M.nu;i++) // 初始化矩阵T的列表头指针向量,各列链表为空
  17.      M.chead[i]=NULL;
  18.  }
  19.  void InsertAscend(CrossList &M,OLink p)
  20.  { // 初始条件:稀疏矩阵M存在,p指向的结点存在。操作结果:按行列升序将p所指结点插入M
  21.    OLink q=M.rhead[p->i]; // q指向待插行表
  22.    if(!q||p->j<q->j) // 待插的行表空或p所指结点的列值小于首结点的列值
  23.    {
  24.      p->right=M.rhead[p->i]; // 插在表头
  25.      M.rhead[p->i]=p;
  26.    }
  27.    else
  28.    {
  29.      while(q->right&&q->right->j<p->j) // q所指不是尾结点且q的下一结点的列值小于p所指结点的列值
  30.        q=q->right; // q向后移
  31.      p->right=q->right; // 将p插在q所指结点之后
  32.      q->right=p;
  33.    }
  34.    q=M.chead[p->j]; // q指向待插列表
  35.    if(!q||p->i<q->i) // 待插的列表空或p所指结点的行值小于首结点的行值
  36.    {
  37.      p->down=M.chead[p->j]; // 插在表头
  38.      M.chead[p->j]=p;
  39.    }
  40.    else
  41.    {
  42.      while(q->down&&q->down->i<p->i) // q所指不是尾结点且q的下一结点的行值小于p所指结点的行值
  43.        q=q->down; // q向下移
  44.      p->down=q->down; // 将p插在q所指结点之下
  45.      q->down=p;
  46.    }
  47.    M.tu++;
  48.  }
  49.  void DestroySMatrix(CrossList &M)
  50.  { // 初始条件:稀疏矩阵M存在。操作结果:销毁稀疏矩阵M
  51.    int i;
  52.    OLink p,q;
  53.    for(i=1;i<=M.mu;i++) // 按行释放结点
  54.    {
  55.      p=*(M.rhead+i);
  56.      while(p)
  57.      {
  58.        q=p;
  59.        p=p->right;
  60.        free(q);
  61.      }
  62.    }
  63.    free(M.rhead);
  64.    free(M.chead);
  65.    InitSMatrix(M);
  66.  }
  67.  void CreateSMatrix(CrossList &M)
  68.  { // 创建稀疏矩阵M,采用十字链表存储表示。算法5.4改
  69.    int i,k;
  70.    OLink p;
  71.    if(M.rhead)
  72.      DestroySMatrix(M);
  73.    printf("请输入稀疏矩阵的行数 列数 非零元个数: ");
  74.    scanf("%d%d%d",&M.mu,&M.nu,&i);
  75.    InitSMatrixList(M); // 初始化M的表头指针向量
  76.    printf("请按任意次序输入%d个非零元的行 列 元素值:/n",M.tu);
  77.    for(k=0;k<i;k++)
  78.    {
  79.      p=(OLink)malloc(sizeof(OLNode)); // 生成结点
  80.      if(!p)
  81.        exit(OVERFLOW);
  82.      scanf("%d%d%d",&p->i,&p->j,&p->e); // 给结点的3个成员赋值
  83.      InsertAscend(M,p); // 将结点p按行列值升序插到矩阵M中
  84.    }
  85.  }
  86.  void PrintSMatrix(CrossList M)
  87.  { // 初始条件:稀疏矩阵M存在。操作结果:按行或按列输出稀疏矩阵M
  88.    int i,j;
  89.    OLink p;
  90.    printf("%d行%d列%d个非零元素/n",M.mu,M.nu,M.tu);
  91.    printf("请输入选择(1.按行输出 2.按列输出): ");
  92.    scanf("%d",&i);
  93.    switch(i)
  94.    {
  95.      case 1: for(j=1;j<=M.mu;j++)
  96.              {
  97.                p=M.rhead[j];
  98.                while(p)
  99.                {
  100.                  cout<<p->i<<"行"<<p->j<<"列值为"<<p->e<<endl;
  101.                  p=p->right;
  102.                }
  103.              }
  104.              break;
  105.      case 2: for(j=1;j<=M.nu;j++)
  106.          {
  107.            p=M.chead[j];
  108.                while(p)
  109.                {
  110.                  cout<<p->i<<"行"<<p->j<<"列值为"<<p->e<<endl;
  111.                  p=p->down;
  112.                }
  113.              }
  114.    }
  115.  }
  116.  void PrintSMatrix1(CrossList M)
  117.  { // 按矩阵形式输出M
  118.    int i,j;
  119.    OLink p;
  120.    for(i=1;i<=M.mu;i++)
  121.    { // 从第1行到最后1行
  122.      p=M.rhead[i]; // p指向该行的第1个非零元素
  123.      for(j=1;j<=M.nu;j++) // 从第1列到最后1列
  124.        if(!p||p->j!=j) // 已到该行表尾或当前结点的列值不等于当前列值
  125.          printf("%-3d",0); // 输出0
  126.        else
  127.        {
  128.          printf("%-3d",p->e);
  129.          p=p->right;
  130.        }
  131.      printf("/n");
  132.    }
  133.  }
  134.  void CopySMatrix(CrossList M,CrossList &T)
  135.  { // 初始条件:稀疏矩阵M存在。操作结果:由稀疏矩阵M复制得到T
  136.    int i;
  137.    OLink p,q;
  138.    if(T.rhead) // 矩阵T存在
  139.      DestroySMatrix(T);
  140.    T.mu=M.mu;
  141.    T.nu=M.nu;
  142.    InitSMatrixList(T); // 初始化T的表头指针向量
  143.    for(i=1;i<=M.mu;i++) // 按行复制
  144.    {
  145.      p=M.rhead[i]; // p指向i行链表头
  146.      while(p) // 没到行尾
  147.      {
  148.        if(!(q=(OLNode*)malloc(sizeof(OLNode)))) // 生成结点q
  149.          exit(OVERFLOW);
  150.        *q=*p; // 给结点q赋值
  151.        InsertAscend(T,q); // 将结点q按行列值升序插到矩阵T中
  152.        p=p->right;
  153.      }
  154.    }
  155.  }
  156.  int comp(int c1,int c2)
  157.  { // AddSMatrix函数要用到,另加
  158.    if(c1<c2)
  159.      return -1;
  160.    if(c1==c2)
  161.      return 0;
  162.    return 1;
  163.  }
  164.  void AddSMatrix(CrossList M,CrossList N,CrossList &Q)
  165.  { // 初始条件:稀疏矩阵M与N的行数和列数对应相等。操作结果:求稀疏矩阵的和Q=M+N
  166.    int i;
  167.    OLink pq,pm,pn;
  168.    if(M.mu!=N.mu||M.nu!=N.nu)
  169.    {
  170.      printf("两个矩阵不是同类型的,不能相加/n");
  171.      exit(OVERFLOW);
  172.    }
  173.    Q.mu=M.mu; // 初始化Q矩阵
  174.    Q.nu=M.nu;
  175.    Q.tu=0; // Q矩阵元素个数的初值为0
  176.    InitSMatrixList(Q); // 初始化Q的表头指针向量
  177.    for(i=1;i<=M.mu;i++) // 按行的顺序相加
  178.    {
  179.      pm=M.rhead[i]; // pm指向矩阵M的第i行的第1个结点
  180.      pn=N.rhead[i]; // pn指向矩阵N的第i行的第1个结点
  181.      while(pm&&pn) // pm和pn均不空
  182.      {
  183.        pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
  184.        switch(comp(pm->j,pn->j))
  185.        {
  186.      case -1: *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
  187.           InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  188.           pm=pm->right; // 指针向后移
  189.           break;
  190.      case  0: *pq=*pm; // M、N矩阵的列相等,元素值相加
  191.           pq->e+=pn->e;
  192.                   if(pq->e!=0) // 和为非零元素
  193.                     InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  194.                   else
  195.                     free(pq); // 释放结点
  196.                   pm=pm->right; // 指针向后移
  197.                   pn=pn->right;
  198.                   break;
  199.          case  1: *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
  200.                   InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  201.                   pn=pn->right; // 指针向后移
  202.        }
  203.      }
  204.      while(pm) // pn=NULL
  205.      {
  206.        pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
  207.        *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
  208.        InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  209.        pm=pm->right; // 指针向后移
  210.      }
  211.      while(pn) // pm=NULL
  212.      {
  213.        pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
  214.        *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
  215.        InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  216.        pn=pn->right; // 指针向后移
  217.      }
  218.    }
  219.    if(Q.tu==0) // Q矩阵元素个数为0
  220.      DestroySMatrix(Q); // 销毁矩阵Q
  221.  }
  222.  void SubtSMatrix(CrossList M,CrossList N,CrossList &Q)
  223.  { // 初始条件:稀疏矩阵M与N的行数和列数对应相等。操作结果:求稀疏矩阵的差Q=M-N
  224.    int i;
  225.    OLink pq,pm,pn;
  226.    if(M.mu!=N.mu||M.nu!=N.nu)
  227.    {
  228.      printf("两个矩阵不是同类型的,不能相减/n");
  229.      exit(OVERFLOW);
  230.    }
  231.    Q.mu=M.mu; // 初始化Q矩阵
  232.    Q.nu=M.nu;
  233.    Q.tu=0; // Q矩阵元素个数的初值为0
  234.    InitSMatrixList(Q); // 初始化Q的表头指针向量
  235.    for(i=1;i<=M.mu;i++) // 按行的顺序相减
  236.    {
  237.      pm=M.rhead[i]; // pm指向矩阵M的第i行的第1个结点
  238.      pn=N.rhead[i]; // pn指向矩阵N的第i行的第1个结点
  239.      while(pm&&pn) // pm和pn均不空
  240.      {
  241.        pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
  242.        switch(comp(pm->j,pn->j))
  243.        {
  244.      case -1: *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
  245.           InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  246.           pm=pm->right; // 指针向后移
  247.           break;
  248.      case  0: *pq=*pm; // M、N矩阵的列相等,元素值相减
  249.                   pq->e-=pn->e;
  250.                   if(pq->e!=0) // 差为非零元素
  251.                     InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  252.                   else
  253.                     free(pq); // 释放结点
  254.                   pm=pm->right; // 指针向后移
  255.                   pn=pn->right;
  256.                   break;
  257.          case  1: *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
  258.                   pq->e*=-1; // 求反
  259.                   InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  260.                   pn=pn->right; // 指针向后移
  261.        }
  262.      }
  263.      while(pm) // pn=NULL
  264.      {
  265.        pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
  266.        *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
  267.        InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  268.        pm=pm->right; // 指针向后移
  269.      }
  270.      while(pn) // pm=NULL
  271.      {
  272.        pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
  273.        *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
  274.        pq->e*=-1; // 求反
  275.        InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  276.        pn=pn->right; // 指针向后移
  277.      }
  278.    }
  279.    if(Q.tu==0) // Q矩阵元素个数为0
  280.      DestroySMatrix(Q); // 销毁矩阵Q
  281.  }
  282.  void MultSMatrix(CrossList M,CrossList N,CrossList &Q)
  283.  { // 初始条件:稀疏矩阵M的列数等于N的行数。操作结果:求稀疏矩阵乘积Q=M×N
  284.    int i,j,e;
  285.    OLink pq,pm,pn;
  286.    InitSMatrix(Q);
  287.    Q.mu=M.mu;
  288.    Q.nu=N.nu;
  289.    Q.tu=0;
  290.    InitSMatrixList(Q); // 初始化Q的表头指针向量
  291.    for(i=1;i<=Q.mu;i++)
  292.      for(j=1;j<=Q.nu;j++)
  293.      {
  294.        pm=M.rhead[i];
  295.        pn=N.chead[j];
  296.        e=0;
  297.        while(pm&&pn)
  298.          switch(comp(pn->i,pm->j))
  299.          {
  300.            case -1: pn=pn->down; // 列指针后移
  301.                     break;
  302.            case  0: e+=pm->e*pn->e; // 乘积累加
  303.             pn=pn->down; // 行列指针均后移
  304.                     pm=pm->right;
  305.                     break;
  306.            case  1: pm=pm->right; // 行指针后移
  307.          }
  308.        if(e) // 值不为0
  309.        {
  310.          pq=(OLink)malloc(sizeof(OLNode)); // 生成结点
  311.          if(!pq) // 生成结点失败
  312.            exit(OVERFLOW);
  313.          pq->i=i; // 给结点赋值
  314.          pq->j=j;
  315.          pq->e=e;
  316.          InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
  317.        }
  318.      }
  319.    if(Q.tu==0) // Q矩阵元素个数为0
  320.      DestroySMatrix(Q); // 销毁矩阵Q
  321.  }
  322.  void TransposeSMatrix(CrossList M,CrossList &T)
  323.  { // 初始条件:稀疏矩阵M存在。操作结果:求稀疏矩阵M的转置矩阵T
  324.    int u,i;
  325.    OLink *head,p,q,r;
  326.    CopySMatrix(M,T); // T=M
  327.    u=T.mu; // 交换T.mu和T.nu
  328.    T.mu=T.nu;
  329.    T.nu=u;
  330.    head=T.rhead; // 交换T.rhead和T.chead
  331.    T.rhead=T.chead;
  332.    T.chead=head;
  333.    for(u=1;u<=T.mu;u++) // 对T的每一行
  334.    {
  335.      p=T.rhead[u]; // p为行表头
  336.      while(p) // 没到表尾,对T的每一结点
  337.      {
  338.        q=p->down; // q指向下一个结点
  339.        i=p->i; // 交换.i和.j
  340.        p->i=p->j;
  341.        p->j=i;
  342.        r=p->down; // 交换.down和.right
  343.        p->down=p->right;
  344.        p->right=r;
  345.        p=q; // p指向下一个结点
  346.      }
  347.    }
  348.  }
  1.  // bo5-5.cpp 广义表的头尾链表存储(存储结构由c5-5.h定义)的基本操作(11个),包括算法5.5,5.6,5.7
  2.  #include"func5-1.cpp" // 算法5.8
  3.  void InitGList(GList &L)
  4.  { // 创建空的广义表L
  5.    L=NULL;
  6.  }
  7.  void CreateGList(GList &L,SString S) // 算法5.7
  8.  { // 采用头尾链表存储结构,由广义表的书写形式串S创建广义表L。设emp="()"
  9.    SString sub,hsub,emp;
  10.    GList p,q;
  11.    StrAssign(emp,"()"); // 空串emp="()"
  12.    if(!StrCompare(S,emp)) // S="()"
  13.      L=NULL; // 创建空表
  14.    else // S不是空串
  15.    {
  16.      if(!(L=(GList)malloc(sizeof(GLNode)))) // 建表结点
  17.        exit(OVERFLOW);
  18.      if(StrLength(S)==1) // S为单原子,只会出现在递归调用中
  19.      {
  20.        L->tag=ATOM;
  21.        L->atom=S[1]; // 创建单原子广义表
  22.      }
  23.      else // S为表
  24.      {
  25.        L->tag=LIST;
  26.        p=L;
  27.        SubString(sub,S,2,StrLength(S)-2); // 脱外层括号(去掉第1个字符和最后1个字符)给串sub
  28.        do
  29.        { // 重复建n个子表
  30.          sever(sub,hsub); // 从sub中分离出表头串hsub
  31.          CreateGList(p->ptr.hp,hsub);
  32.          q=p;
  33.          if(!StrEmpty(sub)) // 表尾不空
  34.          {
  35.            if(!(p=(GLNode *)malloc(sizeof(GLNode))))
  36.              exit(OVERFLOW);
  37.            p->tag=LIST;
  38.        q->ptr.tp=p;
  39.          }
  40.        }while(!StrEmpty(sub));
  41.        q->ptr.tp=NULL;
  42.      }
  43.    }
  44.  }
  45.  void DestroyGList(GList &L)
  46.  { // 销毁广义表L
  47.    GList q1,q2;
  48.    if(L)
  49.    {
  50.      if(L->tag==LIST) // 删除表结点
  51.      {
  52.        q1=L->ptr.hp; // q1指向表头
  53.        q2=L->ptr.tp; // q2指向表尾
  54.        DestroyGList(q1); // 销毁表头
  55.        DestroyGList(q2); // 销毁表尾
  56.      }
  57.      free(L);
  58.      L=NULL;
  59.    }
  60.  }
  61.  void CopyGList(GList &T,GList L)
  62.  { // 采用头尾链表存储结构,由广义表L复制得到广义表T。算法5.6
  63.    if(!L) // 复制空表
  64.      T=NULL;
  65.    else
  66.    {
  67.      T=(GList)malloc(sizeof(GLNode)); // 建表结点
  68.      if(!T)
  69.        exit(OVERFLOW);
  70.      T->tag=L->tag;
  71.      if(L->tag==ATOM)
  72.        T->atom=L->atom; // 复制单原子
  73.      else
  74.      {
  75.        CopyGList(T->ptr.hp,L->ptr.hp); // 递归复制子表
  76.        CopyGList(T->ptr.tp,L->ptr.tp);
  77.      }
  78.    }
  79.  }
  80.  int GListLength(GList L)
  81.  { // 返回广义表的长度,即元素个数
  82.    int len=0;
  83.    while(L)
  84.    {
  85.      L=L->ptr.tp;
  86.      len++;
  87.    }
  88.    return len;
  89.  }
  90.  int GListDepth(GList L)
  91.  { // 采用头尾链表存储结构,求广义表L的深度。算法5.5
  92.    int max,dep;
  93.    GList pp;
  94.    if(!L)
  95.      return 1; // 空表深度为1
  96.    if(L->tag==ATOM)
  97.      return 0; // 原子深度为0,只会出现在递归调用中
  98.    for(max=0,pp=L;pp;pp=pp->ptr.tp)
  99.    {
  100.      dep=GListDepth(pp->ptr.hp); // 递归求以pp->ptr.hp为头指针的子表深度
  101.      if(dep>max)
  102.        max=dep;
  103.    }
  104.    return max+1; // 非空表的深度是各元素的深度的最大值加1
  105.  }
  106.  Status GListEmpty(GList L)
  107.  { // 判定广义表是否为空
  108.    if(!L)
  109.      return TRUE;
  110.    else
  111.      return FALSE;
  112.  }
  113.  GList GetHead(GList L)
  114.  { // 生成广义表L的表头元素,返回指向这个元素的指针
  115.    GList h,p;
  116.    if(!L) // 空表无表头
  117.      return NULL;
  118.    p=L->ptr.hp; // p指向L的表头元素
  119.    CopyGList(h,p); // 将表头元素复制给h
  120.    return h;
  121.  }
  122.  GList GetTail(GList L)
  123.  { // 将广义表L的表尾生成为广义表,返回指向这个新广义表的指针
  124.    GList t;
  125.    if(!L) // 空表无表尾
  126.      return NULL;
  127.    CopyGList(t,L->ptr.tp); // 将L的表尾拷给t
  128.    return t;
  129.  }
  130.  void InsertFirst_GL(GList &L,GList e)
  131.  { // 初始条件:广义表存在。操作结果:插入元素e(也可能是子表)作为广义表L的第1元素(表头)
  132.    GList p=(GList)malloc(sizeof(GLNode)); // 生成新结点
  133.    if(!p)
  134.      exit(OVERFLOW);
  135.    p->tag=LIST; // 结点的类型是表
  136.    p->ptr.hp=e; // 表头指向e
  137.    p->ptr.tp=L; // 表尾指向原表L
  138.    L=p; // L指向新结点
  139.  }
  140.  void DeleteFirst_GL(GList &L,GList &e)
  141.  { // 初始条件:广义表L存在。操作结果:删除广义表L的第一元素,并用e返回其值
  142.    GList p=L; // p指向第1个结点
  143.    e=L->ptr.hp; // e指向L的表头
  144.    L=L->ptr.tp; // L指向原L的表尾
  145.    free(p); // 释放第1个结点
  146.  }
  147.  void Traverse_GL(GList L,void(*v)(AtomType))
  148.  { // 利用递归算法遍历广义表L
  149.    if(L) // L不空
  150.      if(L->tag==ATOM) // L为单原子
  151.        v(L->atom);
  152.      else // L为广义表
  153.      {
  154.        Traverse_GL(L->ptr.hp,v); // 递归遍历L的表头
  155.        Traverse_GL(L->ptr.tp,v); // 递归遍历L的表尾
  156.      }
  157.  }
  1.  // bo5-6.cpp 广义表的扩展线性链表存储(存储结构由c5-6.h定义)的基本操作(13个)
  2.  #include"func5-1.cpp" // 算法5.8
  3.  void InitGList(GList1 &L)
  4.  { // 创建空的广义表L
  5.    L=NULL;
  6.  }
  7.  void CreateGList(GList1 &L,SString S) // 算法5.7改
  8.  { // 采用扩展线性链表存储结构,由广义表的书写形式串S创建广义表L。设emp="()"
  9.    SString emp,sub,hsub;
  10.    GList1 p;
  11.    StrAssign(emp,"()"); // 设emp="()"
  12.    if(!(L=(GList1)malloc(sizeof(GLNode1)))) // 建表结点不成功
  13.      exit(OVERFLOW);
  14.    if(!StrCompare(S,emp)) // 创建空表
  15.    {
  16.      L->tag=LIST;
  17.      L->hp=L->tp=NULL;
  18.    }
  19.    else if(StrLength(S)==1) // 创建单原子广义表
  20.    {
  21.      L->tag=ATOM;
  22.      L->atom=S[1];
  23.      L->tp=NULL;
  24.    }
  25.    else // 创建一般表
  26.    {
  27.      L->tag=LIST;
  28.      L->tp=NULL;
  29.      SubString(sub,S,2,StrLength(S)-2); // 脱外层括号(去掉第1个字符和最后1个字符)给串sub
  30.      sever(sub,hsub); // 从sub中分离出表头串hsub
  31.      CreateGList(L->hp,hsub);
  32.      p=L->hp;
  33.      while(!StrEmpty(sub)) // 表尾不空,则重复建n个子表
  34.      {
  35.        sever(sub,hsub); // 从sub中分离出表头串hsub
  36.        CreateGList(p->tp,hsub);
  37.        p=p->tp;
  38.      };
  39.    }
  40.  }
  41.  void DestroyGList(GList1 &L)
  42.  { // 初始条件:广义表L存在。操作结果:销毁广义表L
  43.    GList1 ph,pt;
  44.    if(L) // L不为空表
  45.    { // 由ph和pt接替L的两个指针
  46.      if(L->tag) // 是子表
  47.        ph=L->hp;
  48.      else // 是原子
  49.        ph=NULL;
  50.      pt=L->tp;
  51.      DestroyGList(ph); // 递归销毁表ph
  52.      DestroyGList(pt); // 递归销毁表pt
  53.      free(L); // 释放L所指结点
  54.      L=NULL; // 令L为空
  55.    }
  56.  }
  57.  void CopyGList(GList1 &T,GList1 L)
  58.  { // 初始条件:广义表L存在。操作结果:由广义表L复制得到广义表T
  59.    T=NULL;
  60.    if(L) // L不空
  61.    {
  62.      T=(GList1)malloc(sizeof(GLNode1));
  63.      if(!T)
  64.        exit(OVERFLOW);
  65.      T->tag=L->tag; // 复制枚举变量
  66.      if(L->tag==ATOM) // 复制共用体部分
  67.        T->atom=L->atom; // 复制单原子
  68.      else
  69.        CopyGList(T->hp,L->hp); // 复制子表
  70.      if(L->tp==NULL) // 到表尾
  71.        T->tp=L->tp;
  72.      else
  73.        CopyGList(T->tp,L->tp); // 复制子表
  74.    }
  75.  }
  76.  int GListLength(GList1 L)
  77.  { // 初始条件:广义表L存在。操作结果:求广义表L的长度,即元素个数
  78.    int len=0;
  79.    GList1 p=L->hp; // p指向第1个元素
  80.    while(p)
  81.    {
  82.      len++;
  83.      p=p->tp;
  84.    };
  85.    return len;
  86.  }
  87.  int GListDepth(GList1 L)
  88.  { // 初始条件:广义表L存在。操作结果:求广义表L的深度
  89.    int max,dep;
  90.    GList1 pp;
  91.    if(L==NULL||L->tag==LIST&&!L->hp)
  92.      return 1; // 空表深度为1
  93.    else if(L->tag==ATOM)
  94.      return 0; // 单原子表深度为0,只会出现在递归调用中
  95.    else // 求一般表的深度
  96.      for(max=0,pp=L->hp;pp;pp=pp->tp)
  97.      {
  98.        dep=GListDepth(pp); // 求以pp为头指针的子表深度
  99.        if(dep>max)
  100.          max=dep;
  101.      }
  102.    return max+1; // 非空表的深度是各元素的深度的最大值加1
  103.  }
  104.  Status GListEmpty(GList1 L)
  105.  { // 初始条件:广义表L存在。操作结果:判定广义表L是否为空
  106.    if(!L||L->tag==LIST&&!L->hp)
  107.      return OK;
  108.    else
  109.      return ERROR;
  110.  }
  111.  GList1 GetHead(GList1 L)
  112.  { // 生成广义表L的表头元素,返回指向这个元素的指针
  113.    GList1 h,p;
  114.    if(!L||L->tag==LIST&&!L->hp) // 空表无表头
  115.      return NULL;
  116.    p=L->hp->tp; // p指向L的表尾
  117.    L->hp->tp=NULL; // 截去L的表尾部分
  118.    CopyGList(h,L->hp); // 将表头元素复制给h
  119.    L->hp->tp=p; // 恢复L的表尾(保持原L不变)
  120.    return h;
  121.  }
  122.  GList1 GetTail(GList1 L)
  123.  { // 将广义表L的表尾生成为广义表,返回指向这个新广义表的指针
  124.    GList1 t,p;
  125.    if(!L||L->tag==LIST&&!L->hp) // 空表无表尾
  126.      return NULL;
  127.    p=L->hp; // p指向表头
  128.    L->hp=p->tp; // 在L中删去表头
  129.    CopyGList(t,L); // 将L的表尾拷给t
  130.    L->hp=p; // 恢复L的表头(保持原L不变)
  131.    return t;
  132.  }
  133.  void InsertFirst_GL(GList1 &L,GList1 e)
  134.  { // 初始条件:广义表存在。操作结果:插入元素e(也可能是子表)作为广义表L的第1元素(表头)
  135.    GList1 p=L->hp;
  136.    L->hp=e;
  137.    e->tp=p;
  138.  }
  139.  void DeleteFirst_GL(GList1 &L,GList1 &e)
  140.  { // 初始条件:广义表L存在。操作结果:删除广义表L的第一元素,并用e返回其值
  141.    if(L&&L->hp)
  142.    {
  143.      e=L->hp;
  144.      L->hp=e->tp;
  145.      e->tp=NULL;
  146.    }
  147.    else
  148.      e=L;
  149.  }
  150.  void Traverse_GL(GList1 L,void(*v)(AtomType))
  151.  { // 利用递归算法遍历广义表L
  152.    GList1 hp;
  153.    if(L) // L不空
  154.    {
  155.      if(L->tag==ATOM) // L为单原子
  156.      {
  157.        v(L->atom);
  158.        hp=NULL;
  159.      }
  160.      else // L为子表
  161.        hp=L->hp;
  162.      Traverse_GL(hp,v);
  163.      Traverse_GL(L->tp,v);
  164.    }
  165.  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章