⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bo5-4.cpp

📁 严慰敏
💻 CPP
字号:
 // bo5-4.cpp 稀疏矩阵的十字链表存储(存储结构由c5-4.h定义)的基本操作(9个),包括算法5.4

 void InitSMatrix(CrossList &M)
 { // 初始化M(CrossList类型的变量必须初始化,否则创建、复制矩阵将出错)。加
   M.rhead=M.chead=NULL;
   M.mu=M.nu=M.tu=0;
 }

 void InitSMatrixList(CrossList &M)
 { // 初始化十字链表表头指针向量。加
   int i;
   if(!(M.rhead=(OLink*)malloc((M.mu+1)*sizeof(OLink)))) // 生成行表头指针向量
     exit(OVERFLOW);
   if(!(M.chead=(OLink*)malloc((M.nu+1)*sizeof(OLink)))) // 生成列表头指针向量
     exit(OVERFLOW);
   for(i=1;i<=M.mu;i++) // 初始化矩阵T的行表头指针向量,各行链表为空
     M.rhead[i]=NULL;
   for(i=1;i<=M.nu;i++) // 初始化矩阵T的列表头指针向量,各列链表为空
     M.chead[i]=NULL;
 }

 void InsertAscend(CrossList &M,OLink p)
 { // 初始条件:稀疏矩阵M存在,p指向的结点存在。操作结果:按行列升序将p所指结点插入M
   OLink q=M.rhead[p->i]; // q指向待插行表
   if(!q||p->j<q->j) // 待插的行表空或p所指结点的列值小于首结点的列值
   {
     p->right=M.rhead[p->i]; // 插在表头
     M.rhead[p->i]=p;
   }
   else
   {
     while(q->right&&q->right->j<p->j) // q所指不是尾结点且q的下一结点的列值小于p所指结点的列值
       q=q->right; // q向后移
     p->right=q->right; // 将p插在q所指结点之后
     q->right=p;
   }
   q=M.chead[p->j]; // q指向待插列表
   if(!q||p->i<q->i) // 待插的列表空或p所指结点的行值小于首结点的行值
   {
     p->down=M.chead[p->j]; // 插在表头
     M.chead[p->j]=p;
   }
   else
   {
     while(q->down&&q->down->i<p->i) // q所指不是尾结点且q的下一结点的行值小于p所指结点的行值
       q=q->down; // q向下移
     p->down=q->down; // 将p插在q所指结点之下
     q->down=p;
   }
   M.tu++;
 }

 void DestroySMatrix(CrossList &M)
 { // 初始条件:稀疏矩阵M存在。操作结果:销毁稀疏矩阵M
   int i;
   OLink p,q;
   for(i=1;i<=M.mu;i++) // 按行释放结点
   {
     p=*(M.rhead+i);
     while(p)
     {
       q=p;
       p=p->right;
       free(q);
     }
   }
   free(M.rhead);
   free(M.chead);
   InitSMatrix(M);
 }

 void CreateSMatrix(CrossList &M)
 { // 创建稀疏矩阵M,采用十字链表存储表示。算法5.4改
   int i,k;
   OLink p;
   if(M.rhead)
     DestroySMatrix(M);
   printf("请输入稀疏矩阵的行数 列数 非零元个数: ");
   scanf("%d%d%d",&M.mu,&M.nu,&i);
   InitSMatrixList(M); // 初始化M的表头指针向量
   printf("请按任意次序输入%d个非零元的行 列 元素值:\n",M.tu);
   for(k=0;k<i;k++)
   {
     p=(OLink)malloc(sizeof(OLNode)); // 生成结点
     if(!p)
       exit(OVERFLOW);
     scanf("%d%d%d",&p->i,&p->j,&p->e); // 给结点的3个成员赋值
     InsertAscend(M,p); // 将结点p按行列值升序插到矩阵M中
   }
 }

 void PrintSMatrix(CrossList M)
 { // 初始条件:稀疏矩阵M存在。操作结果:按行或按列输出稀疏矩阵M
   int i,j;
   OLink p;
   printf("%d行%d列%d个非零元素\n",M.mu,M.nu,M.tu);
   printf("请输入选择(1.按行输出 2.按列输出): ");
   scanf("%d",&i);
   switch(i)
   {
     case 1: for(j=1;j<=M.mu;j++)
             {
               p=M.rhead[j];
               while(p)
               {
                 cout<<p->i<<"行"<<p->j<<"列值为"<<p->e<<endl;
                 p=p->right;
               }
             }
             break;
     case 2: for(j=1;j<=M.nu;j++)
	     {
	       p=M.chead[j];
               while(p)
               {
                 cout<<p->i<<"行"<<p->j<<"列值为"<<p->e<<endl;
                 p=p->down;
               }
             }
   }
 }

 void PrintSMatrix1(CrossList M)
 { // 按矩阵形式输出M
   int i,j;
   OLink p;
   for(i=1;i<=M.mu;i++)
   { // 从第1行到最后1行
     p=M.rhead[i]; // p指向该行的第1个非零元素
     for(j=1;j<=M.nu;j++) // 从第1列到最后1列
       if(!p||p->j!=j) // 已到该行表尾或当前结点的列值不等于当前列值
         printf("%-3d",0); // 输出0
       else
       {
         printf("%-3d",p->e);
         p=p->right;
       }
     printf("\n");
   }
 }

 void CopySMatrix(CrossList M,CrossList &T)
 { // 初始条件:稀疏矩阵M存在。操作结果:由稀疏矩阵M复制得到T
   int i;
   OLink p,q;
   if(T.rhead) // 矩阵T存在
     DestroySMatrix(T);
   T.mu=M.mu;
   T.nu=M.nu;
   InitSMatrixList(T); // 初始化T的表头指针向量
   for(i=1;i<=M.mu;i++) // 按行复制
   {
     p=M.rhead[i]; // p指向i行链表头
     while(p) // 没到行尾
     {
       if(!(q=(OLNode*)malloc(sizeof(OLNode)))) // 生成结点q
         exit(OVERFLOW);
       *q=*p; // 给结点q赋值
       InsertAscend(T,q); // 将结点q按行列值升序插到矩阵T中
       p=p->right;
     }
   }
 }

 int comp(int c1,int c2)
 { // AddSMatrix函数要用到,另加
   if(c1<c2)
     return -1;
   if(c1==c2)
     return 0;
   return 1;
 }

 void AddSMatrix(CrossList M,CrossList N,CrossList &Q)
 { // 初始条件:稀疏矩阵M与N的行数和列数对应相等。操作结果:求稀疏矩阵的和Q=M+N
   int i;
   OLink pq,pm,pn;
   if(M.mu!=N.mu||M.nu!=N.nu)
   {
     printf("两个矩阵不是同类型的,不能相加\n");
     exit(OVERFLOW);
   }
   Q.mu=M.mu; // 初始化Q矩阵
   Q.nu=M.nu;
   Q.tu=0; // Q矩阵元素个数的初值为0
   InitSMatrixList(Q); // 初始化Q的表头指针向量
   for(i=1;i<=M.mu;i++) // 按行的顺序相加
   {
     pm=M.rhead[i]; // pm指向矩阵M的第i行的第1个结点
     pn=N.rhead[i]; // pn指向矩阵N的第i行的第1个结点
     while(pm&&pn) // pm和pn均不空
     {
       pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
       switch(comp(pm->j,pn->j))
       {
	 case -1: *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
		  InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
		  pm=pm->right; // 指针向后移
		  break;
	 case  0: *pq=*pm; // M、N矩阵的列相等,元素值相加
		  pq->e+=pn->e;
                  if(pq->e!=0) // 和为非零元素
                    InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
                  else
                    free(pq); // 释放结点
                  pm=pm->right; // 指针向后移
                  pn=pn->right;
                  break;
         case  1: *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
                  InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
                  pn=pn->right; // 指针向后移
       }
     }
     while(pm) // pn=NULL
     {
       pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
       *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
       InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
       pm=pm->right; // 指针向后移
     }
     while(pn) // pm=NULL
     {
       pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
       *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
       InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
       pn=pn->right; // 指针向后移
     }
   }
   if(Q.tu==0) // Q矩阵元素个数为0
     DestroySMatrix(Q); // 销毁矩阵Q
 }

 void SubtSMatrix(CrossList M,CrossList N,CrossList &Q)
 { // 初始条件:稀疏矩阵M与N的行数和列数对应相等。操作结果:求稀疏矩阵的差Q=M-N
   int i;
   OLink pq,pm,pn;
   if(M.mu!=N.mu||M.nu!=N.nu)
   {
     printf("两个矩阵不是同类型的,不能相减\n");
     exit(OVERFLOW);
   }
   Q.mu=M.mu; // 初始化Q矩阵
   Q.nu=M.nu;
   Q.tu=0; // Q矩阵元素个数的初值为0
   InitSMatrixList(Q); // 初始化Q的表头指针向量
   for(i=1;i<=M.mu;i++) // 按行的顺序相减
   {
     pm=M.rhead[i]; // pm指向矩阵M的第i行的第1个结点
     pn=N.rhead[i]; // pn指向矩阵N的第i行的第1个结点
     while(pm&&pn) // pm和pn均不空
     {
       pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
       switch(comp(pm->j,pn->j))
       {
	 case -1: *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
		  InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
		  pm=pm->right; // 指针向后移
		  break;
	 case  0: *pq=*pm; // M、N矩阵的列相等,元素值相减
                  pq->e-=pn->e;
                  if(pq->e!=0) // 差为非零元素
                    InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
                  else
                    free(pq); // 释放结点
                  pm=pm->right; // 指针向后移
                  pn=pn->right;
                  break;
         case  1: *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
                  pq->e*=-1; // 求反
                  InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
                  pn=pn->right; // 指针向后移
       }
     }
     while(pm) // pn=NULL
     {
       pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
       *pq=*pm; // M的列<N的列,将矩阵M的当前元素值赋给pq
       InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
       pm=pm->right; // 指针向后移
     }
     while(pn) // pm=NULL
     {
       pq=(OLink)malloc(sizeof(OLNode)); // 生成矩阵Q的结点
       *pq=*pn; // M的列>N的列,将矩阵N的当前元素值赋给pq
       pq->e*=-1; // 求反
       InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
       pn=pn->right; // 指针向后移
     }
   }
   if(Q.tu==0) // Q矩阵元素个数为0
     DestroySMatrix(Q); // 销毁矩阵Q
 }

 void MultSMatrix(CrossList M,CrossList N,CrossList &Q)
 { // 初始条件:稀疏矩阵M的列数等于N的行数。操作结果:求稀疏矩阵乘积Q=M×N
   int i,j,e;
   OLink pq,pm,pn;
   InitSMatrix(Q);
   Q.mu=M.mu;
   Q.nu=N.nu;
   Q.tu=0;
   InitSMatrixList(Q); // 初始化Q的表头指针向量
   for(i=1;i<=Q.mu;i++)
     for(j=1;j<=Q.nu;j++)
     {
       pm=M.rhead[i];
       pn=N.chead[j];
       e=0;
       while(pm&&pn)
         switch(comp(pn->i,pm->j))
         {
           case -1: pn=pn->down; // 列指针后移
                    break;
           case  0: e+=pm->e*pn->e; // 乘积累加
		    pn=pn->down; // 行列指针均后移
                    pm=pm->right;
                    break;
           case  1: pm=pm->right; // 行指针后移
         }
       if(e) // 值不为0
       {
         pq=(OLink)malloc(sizeof(OLNode)); // 生成结点
         if(!pq) // 生成结点失败
           exit(OVERFLOW);
         pq->i=i; // 给结点赋值
         pq->j=j;
         pq->e=e;
         InsertAscend(Q,pq); // 将结点pq按行列值升序插到矩阵Q中
       }
     }
   if(Q.tu==0) // Q矩阵元素个数为0
     DestroySMatrix(Q); // 销毁矩阵Q
 }

 void TransposeSMatrix(CrossList M,CrossList &T)
 { // 初始条件:稀疏矩阵M存在。操作结果:求稀疏矩阵M的转置矩阵T
   int u,i;
   OLink *head,p,q,r;
   CopySMatrix(M,T); // T=M
   u=T.mu; // 交换T.mu和T.nu
   T.mu=T.nu;
   T.nu=u;
   head=T.rhead; // 交换T.rhead和T.chead
   T.rhead=T.chead;
   T.chead=head;
   for(u=1;u<=T.mu;u++) // 对T的每一行
   {
     p=T.rhead[u]; // p为行表头
     while(p) // 没到表尾,对T的每一结点
     {
       q=p->down; // q指向下一个结点
       i=p->i; // 交换.i和.j
       p->i=p->j;
       p->j=i;
       r=p->down; // 交换.down和.right
       p->down=p->right;
       p->right=r;
       p=q; // p指向下一个结点
     }
   }
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -