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.  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章