稀疏矩阵与广义表的操作(用C写的)

该程序有两个菜单:主菜单与副菜单。副菜单有分为A菜单和B菜单,A菜单目录是稀疏矩阵的操作,B菜单目录是广义表的操作
运行界面:

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
 typedef struct
 {
   int i,j; /*  行下标,列下标 */
   int e; /*  非零元素值 */
 }triple;
 typedef struct tsmatrix
 {
   triple data[MAXSIZE];
   int mu,nu,tu;
 }rlsmatrix;

 

typedef struct lnode
{
 int tag;    /*结点类型标识,0表示原子结点,1表示表或子表结点*/
     union
     { int  data;  
        struct lnode *sublist; /*存储子表的地址*/
     } val;
     struct lnode *link;   /*指向下一个元素*/
} GLNode;//广义表结构定义

 

 


void  createsmatrix(rlsmatrix *M)// 创建稀疏矩阵M */
{
   int e,i,m,n;
  // M->data[0].i=0; /*  为以下比较顺序做准备 */
   printf("请输入矩阵的行数,列数,和非零元素的个数:");
   scanf("%d",&M->mu);
   scanf("%d",&M->nu);
   scanf("%d",&M->tu);
   for(i=0;i<M->tu;i++)
   {
       printf("请按行序顺序输入第%d个非零元素所在的行(0~%d),列(0~%d),元素值:",i,M->mu,M->nu);
       scanf("%d",&m);
    scanf("%d",&n);
    scanf("%d",&e);
       if(m<0||m>M->mu||n<0||n>M->nu) /*行或列超出范围 */
         {printf("行或列超出范围");
    continue;
  
    }
      // if(m<=M->mu||n<=M->nu) /*行或列的顺序有错*/
        // {printf("行或列的顺序有错");
   /// continue;
  //
   // }
     M->data[i].i=m;
     M->data[i].j=n;
     M->data[i].e=e;
   }
 
}

void transposesmatrix(rlsmatrix M,rlsmatrix *T)// 求矩阵的快速转置
 { /* cpos存放每列的第一个非零元素的地址,num数组存放每列中非零元素的个数 */
   int col,num[MAXSIZE],cpot[MAXSIZE];
   int t,p,q;
  
   T->mu=M.nu;
   T->nu=M.mu;
   T->tu=M.tu;
   if(T->tu)
   {
    for(col=0;col<M.nu;col++)
     num[col]=0;
    for(t=0;t<M.tu;t++)
     ++num[M.data[t].j];
    for(t=0;t<M.tu;t++)
     if(M.data[t].j==0)
     {
    cpot[0]=M.data[t].i;
     break;
     }
    for(col=1;col<M.nu;col++)

    cpot[col]=cpot[col-1]+num[col-1];

    for(p=0;p<M.tu;p++)
    {
     col=M.data[p].j;
     q=cpot[col];
     T->data[p].i=M.data[q].j;
     T->data[p].j=M.data[q].i;
     T->data[p].e=M.data[q].e;
     cpot[col]++;
    
    
    }
   }
  
 }
void multsmatrix(rlsmatrix M,rlsmatrix N,rlsmatrix *T)//矩阵相乘
{
      rlsmatrix K;
   int p,t=0;
    T->mu=M.mu;
      T->nu=N.nu;
   T->tu=0;
 if(M.nu!=N.mu)
        {printf("两矩阵无法相乘/n");}
 else {
     transposesmatrix(N,&K);
  for(t=0;t<M.tu;t++)
   for(p=0;p<K.tu;p++)
    if(M.data[t].j==K.data[p].j)
    {
     T->data[T->tu].i=M.data[t].i;
     T->data[T->tu].j=K.data[p].i;
     T->data[T->tu].e=M.data[t].e*K.data[p].e;
     T->tu++;
   }
    for(t=0;t<T->tu;t++)
     if((T->data[t].i==T->data[t+1].i)&&(T->data[t].j==T->data[t+1].j))
     {
      T->data[t].e+=T->data[t+1].e;
     for(p=1;p<T->tu-1;p++)
                     T->data[t+p]=T->data[t+1+p];
     T->tu--;
     }
 }
 }
void Addmatrix(rlsmatrix M,rlsmatrix N,rlsmatrix *W)//两矩阵相加
{
 int p,q;
 W->mu=M.mu;
    W->nu=M.nu;
 W->tu=0;
 if((M.mu!=N.mu)&&(M.nu!=N.nu))
  printf("两矩阵不能相加:/n");
 else {
 
  
 for(p=0,q=0;p<M.tu&&q<N.tu;)
 if((M.data[p].i>M.data[q].i)||((M.data[p].i==M.data[q].i)&&(M.data[p].j>M.data[q].j)))
     {
  W->data[W->tu].i=N.data[q].i;
        W->data[W->tu].j=N.data[q].j;
  W->data[W->tu].e=N.data[q].e;
      W->tu++;
     q++;
  }
   
  else if((M.data[p].i<M.data[q].i)||((M.data[p].i==M.data[q].i)&&(M.data[p].j<M.data[q].j)))
  { 
         W->data[W->tu].i=M.data[p].i;
            W->data[W->tu].j=M.data[p].j;
   W->data[W->tu].e=M.data[p].e;
      W->tu++;
      p++;
  }
  else if((M.data[p].i==M.data[q].i)&&(M.data[p].j==M.data[q].j))
  {
   W->data[W->tu].i=M.data[p].i;
            W->data[W->tu].j=M.data[p].j;
   W->data[W->tu].e=M.data[p].e+N.data[q].e;
      W->tu++;
      p++;
      q++;
  }
  while(p<M.tu)
        {
   W->data[W->tu].i=M.data[p].i;
            W->data[W->tu].j=M.data[p].j;
   W->data[W->tu++].e=M.data[p].e;
      p++;
  }
  while(q<N.tu)
        {
   W->data[W->tu].i=N.data[q].i;
            W->data[W->tu].j=N.data[q].j;
   W->data[W->tu++].e=N.data[q].e;
      q++;
  }
 }
}
void searchmatrix(rlsmatrix *M,int e)//查找元素
{
   int n,t=0;
   for(n=0;n<M->tu;n++)
    if(M->data[n].e==e)
    {
    printf("该元素所在的行,列,值为:/n");
     printf("%2d %2d %2d",M->data[n].i,M->data[n].j,M->data[n].e);
     t=-2;
     //break;
   }
   if(t!=-2)
printf("该元素不存/n");
}

void printmatrix(rlsmatrix *M)//稀疏矩阵输出
 {
     int m,n,k;
     printf("矩阵的简化模式是:/n");
     for(m=0;m<M->tu;m++)
     printf("%d,%d,%d/n",M->data[m].i,M->data[m].j,M->data[m].e);
     printf("矩阵的行数是:%d/n",M->mu);
     printf("矩阵的列数是:%d/n",M->nu);
     printf("矩阵中非零元素个数是:%d/n",M->tu);
     printf("矩阵的完整模式的:/n");
  m=0;
     for(n=0;n<M->mu;n++)
        {
            printf("| ");
            for(k=0;k<M->nu;k++)
            {
    
                if(M->data[m].i==n&&M->data[m].j==k)
                    {printf("%3d ",M->data[m].e);
                     m++;}
                else
                    printf("  0 ");
    
             }
            printf("  |/n");
        }
  
 }
 void destrmartix()
 {
         rlsmatrix M,N,T,K,W,Q;
  int choice,e;
  int Y=1;
         printf("/n/t/t==================================================================");
         printf("/n/t/t=            A 矩阵的基本操作有:                                  ");
         printf("/n/t/t=             1---------矩阵的创建                                ");
         printf("/n/t/t=             2---------矩阵的相乘                                ");
         printf("/n/t/t=             3---------矩阵的相加                                ");
         printf("/n/t/t=             4---------矩阵的转置                                ");
         printf("/n/t/t=             5---------元素的查找                                ");
         printf("/n/t/t==================================================================");
  while(Y)
  {
   printf("请(从菜单A(1--5)中)选择:/n");
   scanf("%d",&choice);
         switch(choice){
         case 1:
                 printf("矩阵的创建:/n");
                       printf("请为矩阵M赋值/n");
                       createsmatrix(&M);
                       printmatrix(&M);
        printf("/n");
                    break;
         case 2:
                 printf("矩阵M与矩阵N相乘:/n");
                       printf("请为矩阵N赋值!/n");
                       createsmatrix(&N);
                       printmatrix(&N);
                       multsmatrix(M,N,&T);
                    if(T.tu!=0)
                   {printf("矩阵M*N得矩阵T!/n");
                                printmatrix(&T);
                   }
        printf("/n");
                 break;
            case 3:
                printf("矩阵M与矩阵Q相加:/n");
                printf("请输入要与矩阵M相加的另一矩阵Q:/n");
                      createsmatrix(&Q);
   //printmatrix(&Q);
                      Addmatrix(M,Q,&W);
            if(W.tu!=0)
             {
             printf("相加后的矩阵Q为:/n");
              printmatrix(&W);
              }
      printf("/n");
            break;
    
          case 4:
                         printf("对矩阵T进行转置!");
                         printf("请为矩阵T赋值!/n");
                         createsmatrix(&T);
                         transposesmatrix(T,&K);
                         printf("转置后的矩阵是/n");
                         printmatrix(&K);
       printf("/n");
                  break;
              case 5:
                         printf("查找元素e/n");
                         scanf("%d",&e);
                         searchmatrix(&M,e);
       printf("/n");
                         break; 
             default:
           break;

  }
  printf("菜单A继续吗?Y(1)/N(0)/n");
  scanf("%d",&Y);
  }
 
 }

 


GLNode *CreatGL()//广义表的创建 
{
          char ch;
   GLNode *h;
     ch=getchar();
  //getchar();
        if (ch!='/0')                        /*串未结束判断*/
  {
   h=(GLNode *)malloc(sizeof(GLNode));/*创建一个新结点*/
         if (ch=='(')                    /*当前字符为左括号时*/
            {
          h->tag=1;                    /*新结点作为表头结点*/
                        h->val.sublist=CreatGL();  /*递归构造子表并链到表头结点*/
                  }
          else if (ch==')')
    
           h=NULL;            /*遇到')'字符,子表为空*/
                 else
           {   h->tag=0;  
                h->val.data=ch;
             }
  }
     else
              h=NULL;                           /*串结束,子表为空*/
   
       ch=getchar();
     //if (h!=NULL)        /*串未结束判断*/

        if (ch==',')             
            h->link=CreatGL();  /*递归构造后续子表*/

        else                                /*串结束*/
            h->link=NULL;  
     return h;               /*返回广义表指针*/
}

 

 

int  depthGList(GLNode *h)//求广义表的深度
{
    int max = 0; /* 遍历每个结点,求出所以子表的最大深度 */
    int dep;
    while(h!= NULL)
 {
        if(h->tag == 1)
       {
            dep = depthGList(h->val.sublist);

        if(dep > max)/* 让max始终为同一个所求子表中深度的最大值 */
            {
                max = dep;
            }
        }
        h = h->link;     /* 让gl指向下一个结点 */
    }
 max++;
    return max;      /* 返回表的深度 */
}

 

int Atomnum(GLNode *h) //求广义表的原子的个数
{   int n=0;
 if  (h==NULL) 
             return 0;   /*为空表时返回0*/
 while (h!=NULL)       /*遍历表中的每一个元素*/
 { if (h->tag==1)     /*元素为子表的情况*/
   n=n+Atomnum(h->val.sublist);   /*递归调用求出子表的原子个数*/
    else
     n=n+1;   
        h=h->link;        /*使g指向下一个元素*/
 }
     return(n);    
}

 

 

GLNode *CopyGList(GLNode *L)//广义表的复制
 {
GLNode *T;
    if (!L)
         T = NULL;  // 复制空表
    else {
       T = (GLNode *)malloc(sizeof(GLNode));
       T->tag = L->tag;
       if (L->tag ==0)
           T->val.data= L->val.data;  // 复制单原子结点
       else
           {
            T->val.sublist=CopyGList(L->val.sublist);                                      
           }
        //L=L->link;
       // T=T->link;
        T->link=CopyGList(L->link);
    }
 return T;
}

 

 

void printGList(GLNode *h)//广义表的遍历
{
  
    if(h->tag == 1)
    {
      
        printf("("); /* 存在子表,先输出左括号 */
       
        if(h->val.sublist == NULL)/* 若子表为空,则输出'#'字符 */
        {
            printf(" ");
        }
       
        else/* 若子表非表,则递归输出子表 */
       {
            printGList(h->val.sublist);
        }
       
        printf(")");/* 当一个子表输出结束后,再输出右括号 */
    }
    /* 对单元素结点,则输出该结点的值 */
    else{
        printf("%c", h->val.data);
    }
   
    if(h->link != NULL)/* 输出该结点的后继表 */
    {
       
        printf(", ");/* 先输出逗号分隔 */
      
        printGList(h->link); /* 再递归输出后继表 */
    }
  
}

 

void destrGLNode()
{
int choice;
int k=1,depth,num;
GLNode *h,*T;
         printf("/n/t/t==================================================================");
         printf("/n/t/t=            B 广义表的基本操作如下:                              ");
         printf("/n/t/t=             1---------广义表的建立                              ");
         printf("/n/t/t=             2---------广义表的复制                              ");
         printf("/n/t/t=             3---------求广义表的深度                            ");
         printf("/n/t/t=             4---------求广义表的原子的个数                      ");
         printf("/n/t/t=             5---------广义表的遍历                              ");
         printf("/n/t/t==================================================================");

while(k)
{
printf("请(从菜单B(1--5)中)选择:/n");
scanf("%d",&choice);
 getchar();
switch(choice)
{
case 1:
     printf("广义表h的建立/n");
     h=CreatGL(); //由括号表示串s建立一个带头结点的广义表*
  printf("(");
     printGList(h);
  printf(")");
  printf("/n");
     break;
case 2:
     printf("广义表的h复制到T中/n");
  T = (GLNode *)malloc(sizeof(GLNode));
  T=NULL;
  T=CopyGList(h);
  printf("(");
     printGList(T);
  printf(")");
  printf("/n");
     break;
case 3:
     printf("求广义表h的深度/n");
     depth=depthGList(h);
     printf("广义表h的深度为:%d",depth);
  printf("/n");
     break;
case 4:
     printf("求广义表的原子的个数 /n");
     num=Atomnum(h);
     printf("广义表的原子的个数:%d",num);
  printf("/n");
     break;
case 5: 
     printf("广义表的遍历 /n");
   printf("(");
     printGList(h);
  printf(")");
  printf("/n");
     break;
default:
     break;
}
 printf("菜单B继续继续吗?Y(1)/N(0)/n");
  scanf("%d",&k);
  getchar();
}
}
void main()
{
char w;
int m=1;
printf("进入稀疏矩阵与广义表的基本操作程序:/n");

while(m)
{   
     printf("请选择主菜单:/nA矩阵的基本操作/nB 广义表的基本操作/n");
     w=getchar();
   if(w=='A')
       destrmartix();
    else if(w=='B')
        destrGLNode();
       else
           printf("谢谢使用/n");
    printf("是否继续在主菜单中选择?Y (1)/N(0)");
    scanf("%d",&m);
    getchar();
}
 printf("谢谢使用/n");
}
  

这个程序是我结合课本与自己的想法写的,程序是能够运行,但是从时间与空间上考虑估计不是最好的。

(如果有好的意见或者有哪些需要修改的地方,请提出来,谢谢。)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值