1.多维数组
//多维数组-指针
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE -1
#define OVERFLOW -2
#define MAX_ARRAY_DIM 8
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType *base;
int dim;//维数
int *bounds;//数组维界基址
int *constants;//数组映像函数常量基址
}Array;
Status InitArray(Array *a,int dim,int bounds[]);
Status DestroyArray(Array *a);
Status Locate(Array a,int bounds[],int *pOff);
Status Value(Array a,ElemType *pElem,int bounds[]);
Status Assign(Array *a,ElemType e,int bounds[]);
int main(void){
int bounds[MAX_ARRAY_DIM];
Array a;
ElemType e;
int i,j,k,m,n;
bounds[0]=2;bounds[1]=2;bounds[2]=3;bounds[3]=2;
InitArray(&a,4,bounds);
printf( "多维数组的维数为:4 \n" );
printf( "多维数组各维的大小分别为:2 2 3 2 \n");
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<3;k++)
for(m=0;m<2;m++){
e=i+j+k+m;
bounds[0]=i;
bounds[ 1 ] = j;
bounds[ 2 ] = k;
bounds[ 3 ] = m;
Assign(&a,e,bounds);
}
printf( "多维数组元素为:\n");
n=1;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<3;k++)
for(m=0;m<2;m++){
bounds[0]=i;
bounds[ 1 ] = j;
bounds[ 2 ] = k;
bounds[ 3 ] = m;
Value(a,&e,bounds);
printf("a[%d][%d][%d][%d]=%d ",i,j,k,m,e);
if(n%3==0)
printf("\n");
n++;
}
printf("\n");
DestroyArray(&a);
return 0;
}
Status InitArray(Array *a,int dim,int bounds[]){
int elemtotal=1;
if(dim<1||dim>MAX_ARRAY_DIM)//维度
return ERROR;
a->dim=dim;
a->bounds=(int *)malloc(dim*sizeof(int));//每个维度的基地址
if(a->bounds==NULL)
exit(-1);
for(int i=0;i<dim;i++){
a->bounds[i]=bounds[i];
if(a->bounds[i]<=0)
return ERROR;
elemtotal*=a->bounds[i];//元素总数改变
}
a->base=(ElemType*)malloc(elemtotal*sizeof(ElemType));
if(a->base==NULL)
exit(-1);
// 求映像函数的常数ci
a->constants=(int *)malloc(dim*sizeof(int));
if(a->constants==NULL)
exit(-1);
a->constants[dim-1]=1;
for(int i=dim-2;i>=0;i--)
a->constants[i]=a->bounds[i+1]*a->constants[i+1];
return OK;
}
Status DestroyArray(Array *a){
if(a->base)
free(a->base);
a->base=NULL;
if(a->bounds)
free(a->bounds);
a->bounds=NULL;
if(a->constants)
free(a->constants);
return OK;
}
Status Locate(Array a,int bounds[],int *pOff){//pOff是元素在A中相对地址
*pOff=0;int ind;
for(int i=0;i<a.dim;i++){
ind=bounds[i];
if(ind<0||ind>=a.bounds[i])
return OVERFLOW;
*pOff+=a.constants[i]*ind;
}
return OK;
}
Status Value(Array a,ElemType *pElem,int bounds[]){//e赋值为指定元素的值
int off,result;
result=Locate(a,bounds,&off);
if(result<=0)
return ERROR;
*pElem=*(a.base+off);
}
Status Assign(Array *a,ElemType e,int bounds[]){//e的值赋值给所指定元素
int off,result;
result=Locate(*a,bounds,&off);
if(result<=0)
return ERROR;
*(a->base+off)=e;
}
2.稀疏矩阵相加
//基于三元组的稀疏矩阵转置运算
#include <stdio.h>
#include<stdlib.h>
#define MAX_SIZE 255
#define OK 1
#define TRUE 1
#define ERROR -1
#define FALSE -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef struct{
int i,j;ElemType e;
}Triplet;//结点定义
typedef struct {
int mu,nu,tu;
Triplet data[MAX_SIZE+1
];
}TSMatrix;
Status DestroyMatrix(TSMatrix *t);
void Display(TSMatrix t);
Status Transpose(TSMatrix m,TSMatrix *t);
void FatsTransMatrix(TSMatrix m,TSMatrix *t);
int main( void )
{
TSMatrix matrix, inverseM,inv;
Triplet triplet;
matrix.mu = 6;
matrix.nu = 7;
matrix.tu = 8;
triplet.i = 1;
triplet.j = 2;
triplet.e = 12;
matrix.data[ 1 ] = triplet;
triplet.i = 1;
triplet.j = 3;
triplet.e = 9;
matrix.data[ 2 ] = triplet;
triplet.i = 3;
triplet.j = 1;
triplet.e = -3;
matrix.data[ 3 ] = triplet;
triplet.i = 3;
triplet.j = 6;
triplet.e = 14;
matrix.data[ 4 ] = triplet;
triplet.i = 4;
triplet.j = 3;
triplet.e = 24;
matrix.data[ 5 ] = triplet;
triplet.i = 5;
triplet.j = 2;
triplet.e = 18;
matrix.data[ 6 ] = triplet;
triplet.i = 6;
triplet.j = 1;
triplet.e = 15;
matrix.data[ 7 ] = triplet;
triplet.i = 6;
triplet.j = 4;
triplet.e = -7;
matrix.data[ 8 ] = triplet;
printf( "原始矩阵的三元组表示为:\n" );
Display( matrix );
Transpose(matrix, &inverseM);
printf( "转置矩阵的三元组表示为:\n" );
Display( inverseM );
FatsTransMatrix(matrix, &inv);
printf( "快速转置矩阵的三元组表示为:\n" );
Display( inv );
DestroyMatrix( &matrix );
DestroyMatrix( &inverseM );
return 0;
} // end main
Status DestroyMatrix(TSMatrix *t){
t->mu=0;t->nu=0;t->tu=0;
return OK;
}
void Display(TSMatrix t){
printf(" i j v\n");
for(int i=1;i<=t.tu;i++)
printf("%6d%6d%6d\n",t.data[i].i,t.data[i].j,t.data[i].e);
printf("\n");
}
Status Transpose(TSMatrix m,TSMatrix *t){
int col,p,q;q=1;
t->mu=m.nu;t->nu=m.mu;t->tu=m.tu;
if(t->tu==0)
return OK;
for(col=1;col<=t->nu;col++)
for(p=1;p<=t->tu;p++)
if(m.data[p].j==col){
t->data[q].i=m.data[p].j;
t->data[q].j=m.data[p].i;
t->data[q].e=m.data[p].e;
q++;
}
return OK;
}
void FatsTransMatrix(TSMatrix m,TSMatrix *t){//快速转置
int *num,*copt;//num记录每列非0元素个数,copt记录在t的位置。
int col,p,q,k;
num=(int*)malloc((m.nu+1)*sizeof(int));
if(num==NULL)
exit(-1);
copt=(int*)malloc((m.nu+1)*sizeof(int));
if(copt==NULL)
exit(-1);
t->mu=m.nu;t->nu=m.mu;t->tu=m.tu;
if(t->tu==0)
printf("The Matrix A = 0\n");
else{
for(col=1;col<=m.nu;col++)//遍历m矩阵每一列,初始化num非0元素个数
num[col]=0;//初始化
for(k=1;k<=m.tu;k++)
num[m.data[k].j]++;//记录每一列非0元素个数
for(copt[1]=1,col=2;col<=m.nu;col++)
copt[col]=copt[col-1]+num[col-1];//求每一列第一个非0元素的序号
for(p=1;p<=m.tu;p++){
col=m.data[p].j;//找列号
q=copt[col];//新矩阵的位置
t->data[q].i=m.data[p].j;
t->data[q].j=m.data[p].i;
t->data[q].e=m.data[p].e;
++copt[col];
}
free(num);free(copt);
}
}
3.稀疏矩阵相乘
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
#define MAX_SIZE 12500
#define MAX_RC 1000
typedef struct{
int i;int j;
ElemType e;
}Triplet;
typedef struct{
Triplet data[MAX_SIZE+1];
int rpos[MAX_RC+1];
int mu,nu,tu;
}TSMatrix;
void DestroyMatrix(TSMatrix *t);
void Display(TSMatrix t);
Status Transpose(TSMatrix m,TSMatrix *t);
Status MultMatrix(TSMatrix m,TSMatrix n,TSMatrix *Q);
Status SetRowPosition(TSMatrix *m);
int main(void){
TSMatrix matrix, inverseM, Q;
Triplet triplet;
matrix.mu = 6;
matrix.nu = 7;
matrix.tu = 8;
triplet.i = 1;
triplet.j = 2;
triplet.e = 12;
matrix.data[ 1 ] = triplet;
triplet.i = 1;
triplet.j = 3;
triplet.e = 9;
matrix.data[ 2 ] = triplet;
triplet.i = 3;
triplet.j = 1;
triplet.e = -3;
matrix.data[ 3 ] = triplet;
triplet.i = 3;
triplet.j = 6;
triplet.e = 14;
matrix.data[ 4 ] = triplet;
triplet.i = 4;
triplet.j = 3;
triplet.e = 24;
matrix.data[ 5 ] = triplet;
triplet.i = 5;
triplet.j = 2;
triplet.e = 18;
matrix.data[ 6 ] = triplet;
triplet.i = 6;
triplet.j = 1;
triplet.e = 15;
matrix.data[ 7 ] = triplet;
triplet.i = 6;
triplet.j = 4;
triplet.e = -7;
matrix.data[ 8 ] = triplet;
printf( "原始矩阵的三元组表示为:\n" );
Display( matrix );
Transpose(matrix,&inverseM);
printf( "转置矩阵的三元组表示为:\n" );
Display(inverseM);
SetRowPosition( &matrix );
SetRowPosition( &inverseM );
MultMatrix(matrix,inverseM,&Q);
printf( "矩阵M与其转置阵的乘积Q阵的三元组表示为:\n" );
Display(Q);
DestroyMatrix(&matrix);
DestroyMatrix(&inverseM);
DestroyMatrix(&Q);
return 0;
}
void DestroyMatrix(TSMatrix *t){
t->mu=0;t->nu=0;t->tu=0;
}
void Display(TSMatrix t){
printf(" i j v\n");
for(int i=1;i<=t.tu;i++)
printf("%6d%6d%6d\n",t.data[i].i,t.data[i].j,t.data[i].e);
printf("\n");
}
Status Transpose(TSMatrix m,TSMatrix *t){
int col,p,q;q=1;
t->mu=m.nu;
t->nu=m.mu;
t->tu=m.tu;
if(t->tu==0)
return OK;
for(col=1;col<=t->nu;col++)
for(p=1;p<=t->tu;p++)
if(m.data[p].j==col){
t->data[q].i=m.data[p].j;
t->data[q].j=m.data[p].i;
t->data[q].e=m.data[p].e;
q++;
}
return OK;
}
Status MultMatrix(TSMatrix m,TSMatrix n,TSMatrix *Q){//q=m*n;
int arow,brow,ccol;
int p,q,tp,t;
ElemType ctemp[MAX_SIZE];
if(m.nu!=n.mu)
return ERROR;
Q->mu=m.mu;
Q->nu=n.nu;
Q->tu=0;
if(m.tu*n.tu==0)
return OK;
for(arow=1;arow<=m.mu;arow++){
for(int i=1;i<=Q->nu;i++)
ctemp[i]=0;//当前行累加器清零
Q->rpos[arow]=Q->tu+1;//存储q非零元素每行的第一个元素
if(arow<m.mu)
tp=m.rpos[arow+1];//arow为m,mu-1行,从下一行推出上一行最后一个元素值
else
tp=m.tu+1;//最后一行,为矩阵最后一个元素
for(p=m.rpos[arow];p<tp;p++){//m*n成绩加和
//找到M中当前行每一个非0元素在n中的行号
brow=m.data[p].j;
if(brow<n.mu)//n中当前行的下一行第1个元素
t=n.rpos[brow+1];
else
t=n.tu+1;
for(q=n.rpos[brow];q<t;q++){
ccol=n.data[q].j;
ctemp[ccol]+=m.data[p].e*n.data[q].e;
}
}
for(ccol=1;ccol<=Q->nu;ccol++)
if(ctemp[ccol]!=0){
if(Q->tu++>MAX_SIZE)
return ERROR;
Q->data[Q->tu].i=arow;
Q->data[Q->tu].j=ccol;
Q->data[Q->tu].e=ctemp[ccol];
}
}
return OK;
}
Status SetRowPosition(TSMatrix *m){
int row,p;
int *num,*rpos;
num = (int* )malloc( ( m->mu+ 1 ) * sizeof( int ) );
if( num == NULL )
exit( OVERFLOW );
rpos = (int* )malloc( ( m->mu + 1 )* sizeof( int ) );
if( rpos == NULL )
exit( OVERFLOW );
for(row=1;row<=m->mu;row++)
num[row]=0;
for(p=1;p<m->tu;p++)
num[m->data[p].i]++;
rpos[1]=1;
for(row=2;row<=m->mu;row++)
rpos[row]=rpos[row-1]+num[row-1];
for(row=1;row<=m->mu;row++)
m->rpos[row]=rpos[row];
free(num);
free(rpos);
return OK;
}
4.稀疏矩阵-十字链表
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define FALSE -1
#define TRUE 1
#define ERROR -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef struct OLNode{
int i,j,e;
struct OLNode *right,*down;
}OLNode,*OLink;
typedef struct{
OLink *rhead,*chead;
int mu,nu,tu;
}CrossList;
void Display(CrossList *M);
CrossList CreateMatrix_OL(CrossList M);
void InitMatrix_OL(CrossList *M,int m,int n);
void ClearMatrix_OL(CrossList *M);
void DestroyMatrix_OL(CrossList *M);
void InsertMatrix(CrossList *M,int i,int j,ElemType e);
Status Add(CrossList *M,CrossList *N);
int main(){
// CrossList M;
// M.rhead=NULL;M.chead=NULL;
// M=CreateMatrix_OL(M);
// Display(&M);
CrossList A,B;
InitMatrix_OL(&A,4,5);
InsertMatrix(&A,1,1,1);
InsertMatrix( &A , 2, 4, 1 );
InsertMatrix( &A , 3, 2, 8 );
InsertMatrix( &A , 4, 1, 3 );
Display(&A);
InitMatrix_OL(&B,4,5);
InsertMatrix(&B,1,2,1);
InsertMatrix( &B , 2, 1, 1 );
InsertMatrix( &B , 3, 2, 1 );
InsertMatrix( &B , 4, 1, 3 );
Display(&B);
DestroyMatrix_OL(&B);
Add(&A,&B);
Display(&A);
return 0;
}
CrossList CreateMatrix_OL(CrossList M){
int m,n,t,i,j,e;
OLNode *p,*q;
printf("请输入矩阵的行数、列数、非0元素个数:");
scanf("%d%d%d",&m,&n,&t);
M.mu=m;M.nu=n;M.tu=t;
M.chead=(OLink*)malloc((m+1)*sizeof(OLink));
M.rhead=(OLink*)malloc((n+1)*sizeof(OLink));
if(M.chead==NULL||M.rhead==NULL)
exit(-1);
for(i=1;i<=m;i++)
M.rhead[i]=NULL;
for(j=1;j<=n;j++)
M.chead[j]=NULL;
for(scanf("%d%d%d",&i,&j,&e);i!=0;scanf("%d%d%d",&i,&j,&e)){
p=(OLNode*)malloc(sizeof(OLNode));
if(!p)
exit(-1);
p->i=i;p->j=j;p->e=e;
if(M.rhead[i]==NULL||M.rhead[i]->j>j){
p->right=M.rhead[i];
M.rhead[i]=p;
}
else{
for(q=M.rhead[i];(q->right)&&q->right->j<j;p=p->right) ;
p->right=q->right;
q->right=p;
}
if(M.chead[j]==NULL||M.chead[j]->i>i){
p->down=M.chead[j];
M.chead[j]=p;
}
else{
for(q=M.chead[j];(q->down)&&q->down->i<i;p=p->down) ;
p->down=q->down;
q->down=p;
}
}
return M;
}
void Display(CrossList *M){
int i;
OLNode *q;
printf( "矩阵M的非零元为(按行序排列):\n" );
printf( " i j v\n" );
for(i=1;i<=M->mu;i++){
for(q=(M->rhead)[i];q!=NULL;q=q->right){
printf( "%6d%6d%6d\n", q->i, q->j, q->e );
}
}
// printf( "矩阵M的非零元为(按列序排列):\n" );
// printf( " i j v\n" );
// for(i=1;i<=M->nu;i++){
// for(q=(M->chead)[i];q!=NULL;q=q->down){
// printf( "%6d%6d%6d\n", q->i, q->j, q->e );
// }
// }
}
void InitMatrix_OL(CrossList *M,int m,int n){
int i;
M->mu=m;
M->nu=n;
M->tu=0;
M->rhead=(OLink*)malloc((m+1)*sizeof(OLink));
if(!(M->rhead))
exit(OVERFLOW);
M->chead=(OLink*)malloc((n+1)*sizeof(OLink));
if(!(M->chead))
exit(OVERFLOW);
for(i=0;i<=m;i++)
M->rhead[i]=NULL;
for(i=0;i<=n;i++)
M->chead[i]=NULL;
}
void ClearMatrix_OL(CrossList *M){
int i=0;
OLNode *p,*q;
for(i=1;i<=M->mu;i++){
q=(M->rhead)[i];
while(q!=NULL){
p=q;
q=q->right;
free(p);
}
(M->rhead)[i]=NULL;
}
for(i=1;i<=M->nu;i++)
(M->chead)[i]=NULL;
}
void DestroyMatrix_OL(CrossList *M){
ClearMatrix_OL(M);
if(M->chead)
free(M->chead);
if(M->rhead)
free(M->rhead);
M->mu=0;
M->nu=0;
M->tu=0;
}
void InsertMatrix(CrossList *M,int i,int j,ElemType e){
OLNode *p,*q;
p=(OLNode*)malloc(sizeof(OLNode));
if(!p)
exit(OVERFLOW);
p->i=i;p->j=j;p->e=e;
if((M->rhead)[i]==NULL||(M->rhead)[i]->j>j){
p->right=(M->rhead)[i];
(M->rhead)[i]=p;
}
else{
for(q=(M->rhead)[i];(q->right)&&q->right->j<j;q=q->right) ;
p=p->right;
q->right=p;
}
if((M->chead)[j]==NULL||(M->chead)[j]->i>i){
p->down=(M->chead)[j];
(M->chead)[j]=p;
}
else{
for(q=(M->chead)[j];(q->down)&&q->down->i<i;q=q->down) ;
p->down=q->down;
q->down=p;
}
M->tu++;
}
Status Add(CrossList *M,CrossList *N){
int i,j;
OLNode *pa,*pb,*pre,*p;
OLink *h1=(OLink*)malloc((M->nu+1)*sizeof(OLink));
if(M->mu!=N->mu||M->nu!=N->nu||M->tu*N->tu==0)
return ERROR;
for(j=1;j<M->nu;j++)
h1[j]=M->chead[j];
for(i=1;i<=M->mu;i++){
pa=M->rhead[i];
pb=N->rhead[i];
pre=NULL;
p=(OLNode*)malloc(sizeof(OLNode));
while(pa||pb){
if(!pb)
break;
if(pa==NULL||pa->j>pb->j){
M->tu++;
p->i=pb->i;p->j=pb->j;p->e=pb->e;
if(pre==NULL)
M->rhead[p->i]=p;
else
pre->right=p;
p->right=pa;
pre=p;
if(!M->chead[p->j]||M->chead[p->j]->i>p->i){
p->down=M->chead[p->j];
M->chead[p->j]=p;
}
else{
p->down=h1[p->j]->down;
h1[p->j]->down=p;
}
h1[p->j]=p;
pb=pb->right;
}
else if(pa!=NULL&&pa->j<pb->j){
pre=pa;
pa=pa->right;
}
else if(pa->j==pb->j){
pa->e+=pb->e;
if(pa->e==0){
M->tu--;
if(pre==NULL)
M->rhead[pa->i]=pa->right;
else
pre->right=pa->right;
p=pa;
pa=pa->right;
pb=pb->right;
if(M->chead[p->j]==p)
M->chead[p->j]=h1[p->j]=p->down;
else
h1[p->j]->down=p->down;
free(p);
p=(OLNode*)malloc(sizeof(OLNode));
}
else{
pa=pa->right;
pb=pb->right;
}
}
}
}
return OK;
}
5.广义表
#include<stdio.h>
#include<stdlib.h>
typedef char ElemType;
struct GNode{
int tag;
union{
ElemType data;//原子元素
struct GNode* sublist;//子表
};
struct GNode* next;
};
void CreateGList_char(struct GNode** GL);
void Display(struct GNode *GL);
int GListLength(struct GNode *GL);
int GListDepth(struct GNode *GL);
int main(void){
struct GNode* g;
printf("输入一个广义表,输入格式为: (a,(#),b,(d,(e))); \n");
CreateGList_char(&g);
printf("输出广义表\n");
Display(g);
printf("\n");
printf("广义表的长度为%d\n",GListLength(g->sublist));
printf("广义表的深度为%d\n",GListDepth(g->sublist));
return 0;
}
//"#"为空表
void CreateGList_char(struct GNode** GL){
char ch;
scanf("%c",&ch);
if(ch=='#')
*GL=NULL;
else if(ch=='('){
*GL=(struct GNode*)malloc(sizeof(struct GNode));
(*GL)->tag=1;
CreateGList_char(&((*GL)->sublist));
}
else{
*GL=(struct GNode*)malloc(sizeof(struct GNode));
(*GL)->tag=0;
(*GL)->data=ch;
}
scanf("%c",&ch);
if(*GL==NULL) ;
else if(ch==',')
CreateGList_char(&((*GL)->next));
else if(ch==')'||ch==';')
(*GL)->next=NULL;
}
void Display(struct GNode *GL){
if(GL->tag==1){
printf("%c",'(');
if(GL->sublist==NULL)
printf("%c",'#');
else
Display(GL->sublist);
printf("%c",')');
}
else
printf("%c",GL->data);
if(GL->next!=NULL){
printf("%c",',');
Display(GL->next);
}
}
int GListLength(struct GNode *GL){
if(GL!=NULL)
return 1+GListLength(GL->next);
else return 0;
}
int GListDepth(struct GNode *GL){
int max=0;//最大深度
while(GL!=NULL){
if(GL->tag==1){
int dep=GListDepth(GL->sublist);
if(dep>max)
max=dep;
}
GL=GL->next;
}
return max+1;
}