#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");
}
这个程序是我结合课本与自己的想法写的,程序是能够运行,但是从时间与空间上考虑估计不是最好的。
(如果有好的意见或者有哪些需要修改的地方,请提出来,谢谢。)