• _DataStructure_C_Impl:稀疏矩阵十字链表存储


    #include<stdio.h>
    #include<stdlib.h>
    typedef int DataType;
    typedef struct OLNode{
    	int i,j;
    	DataType e;
    	struct OLNode *right,*down;
    }OLNode,*OLink;
    typedef struct{
    	OLink *rowhead,*colhead;
    	int m,n,len;
    }CrossList;
    //初始化稀疏矩阵
    void InitMatrix(CrossList *M){
    	M->rowhead=M->colhead=NULL;
    	M->m=M->n=M->len=0;
    }
    //销毁稀疏矩阵
    void DestroyMatrix(CrossList *M){
    	int i;
    	OLink p,q;
    	for(i=0;i<M->m;i++){		//按行释放结点空间
    		p=*(M->rowhead+i);
    		while(p){
    			q=p;
    			p=p->right;
    			free(q);
    		}
    	}
    	free(M->rowhead);
    	free(M->colhead);
    	InitMatrix(M);
    }
    //使用十字链表的存储方式创建稀疏矩阵
    void CreateMatrix(CrossList *M){
    	int i,k;
    	int m,n,num;
    	OLNode *p,*q;
    	if(M->rowhead)		//如果链表不空,则释放链表空间
    		DestroyMatrix(M);
    	printf("请输入稀疏矩阵的行数,列数,非零元素的个数: ");
    	scanf("%d,%d,%d",&m,&n,&num);
    	M->m=m;
    	M->n=n;
    	M->len=num;
    	M->rowhead=(OLink*)malloc(m*sizeof(OLink));
    	if(!M->rowhead)
    		exit(-1);
    	M->colhead=(OLink*)malloc(n*sizeof(OLink));
    	if(!M->colhead)
    		exit(-1);
    	for(k=0;k<m;k++)		//初始化十字链表,将链表的行指针置为空
    		M->rowhead[k]=NULL;
    	for(k=0;k<n;k++)		//初始化十字链表,将链表的列指针置为空
    		M->colhead[k]=NULL;
    	printf("请按任意次序输入%d个非零元的行号、列号及元素值:
    ",M->len);
    	for(k=0;k<num;k++){
    		p=(OLNode*)malloc(sizeof(OLNode));	 /*动态生成结点*/
    		if(!p)
    			exit(-1);
    		printf("请输入第%d个非零元的行号(0~%d)、列号(0~%d)及元素值:",k+1,m,n);
    		scanf("%d,%d,%d",&p->i,&p->j,&p->e); /*依次输入行号,列号和元素值*/
    		/*-----------------------------行插入p结点-----------------------------------*/
    		if(M->rowhead[p->i]==NULL||M->rowhead[p->i]->j>p->j)/*如果是第一个结点或当前元素的列号小于表头指向的一个的元素*/
    		{
    			p->right=M->rowhead[p->i];	
    			M->rowhead[p->i]=p;
    		}
    		else
    		{
    			q=M->rowhead[p->i];
    			while(q->right&&q->right->j<p->j)	/*找到要插入结点的位置*/
    				q=q->right; 
    			p->right=q->right;					/*将p插入到q结点之后*/
    			q->right=p;
    		}
    		/*------------------------------列插入p结点-----------------------------------*/
    		q=M->colhead[p->j];						/*将q指向待插入的链表*/
    		if(!q||p->i<q->i)						/*如果p的行号小于表头指针的行号或为空表,则直接插入*/
    		{
    			p->down=M->colhead[p->j]; 
    			M->colhead[p->j]=p;
    		}
    		else
    		{
    			while(q->down&&q->down->i<p->i)		/*如果q的行号小于p的行号,则在链表中查找插入位置*/
    				q=q->down; 
    			p->down=q->down;					/*将p插入到q结点之下*/
    			q->down=p;
    		}
    	}
    }
    //按矩阵形式输出十字链表
    void PrintMatrix(CrossList M){
    	int i,j;
    	OLink p;
    	for(i=0;i<M.m;i++)
    	{ 
    		p=M.rowhead[i];				/*p指向该行的第1个非零元素*/
    		for(j=0;j<M.n;j++)			/*从第一列到最后一列进行输出*/
    			if(!p||p->j!=j)			/*已到该行表尾或当前结点的列值不等于当前列值,则输出0*/
    				printf("%-3d",0);
    			else
    			{
    				printf("%-3d",p->e);
    				p=p->right;
    			}
    			printf("
    ");
    	}
    }
    //按照行序将p插入到稀疏矩阵中
    void InsertMatrix(CrossList *M,OLink p){
    	OLink q=M->rowhead[p->i];		/*q指向待插行表*/
    	if(!q||p->j<q->j)				/*待插的行表空或p所指结点的列值小于首结点的列值,则直接插入*/
    	{
    		p->right=M->rowhead[p->i]; 
    		M->rowhead[p->i]=p;
    	}
    	else
    	{
    		while(q->right&&q->right->j<p->j)	/*q所指不是尾结点且q的下一结点的列值小于p所指结点的列值*/
    			q=q->right; 
    		p->right=q->right; 
    		q->right=p;
    	}
    	q=M->colhead[p->j];					/*q指向待插列表*/
    	if(!q||p->i<q->i)					/*待插的列表空或p所指结点的行值小于首结点的行值*/
    	{
    		p->down=M->colhead[p->j];
    		M->colhead[p->j]=p;
    	}
    	else
    	{
    		while(q->down&&q->down->i<p->i)	/*q所指不是尾结点且q的下一结点的行值小于p所指结点的行值*/
    			q=q->down; 
    		p->down=q->down; 
    		q->down=p;
    	}
    	M->len++;
    }
    //比较两个元素值的大小。如果a>b,返回1,a=b,则返回0,a<b,则返回-1
    int CompareElement(int a,int b){
    	if(a<b)
    		return -1;
    	if(a==b)
    		return 0;
    	return 1;
    }
    //十字链表表示的两个稀疏矩阵相加运算
    void AddMatrix(CrossList A,CrossList B,CrossList *C){
    	int i;
    	OLink pa,pb,pc;
    	if(A.m!=B.m||A.n!=B.n)
    	{
    		printf("两个矩阵不是同类型的,不能相加
    ");
    		exit(-1);
    	}
    	/*初始化矩阵Q*/
    	C->m=A.m; 
    	C->n=A.n;
    	C->len=0;				/*矩阵C的元素个数的初值为0*/
    	/*初始化十字链表*/
    	if(!(C->rowhead=(OLink*)malloc(C->m*sizeof(OLink))))	/*动态生成行表头数组*/
    		exit(-1);
    	if(!(C->colhead=(OLink*)malloc(C->n*sizeof(OLink))))	/*动态生成列表头数组*/
    		exit(-1);
    	for(i=0;i<C->m;i++)		/*初始化矩阵C的行表头指针数组,各行链表为空*/
    		C->rowhead[i]=NULL;
    	for(i=0;i<C->n;i++)		/*初始化矩阵C的列表头指针数组,各列链表为空*/
    		C->colhead[i]=NULL;
    	/*将稀疏矩阵按行的顺序相加*/
    	for(i=0;i<A.m;i++)
    	{
    		pa=A.rowhead[i];	/*pa指向矩阵A的第i行的第1个结点*/
    		pb=B.rowhead[i];	/*pb指向矩阵B的第i行的第1个结点*/
    		while(pa&&pb) 
    		{
    			pc=(OLink)malloc(sizeof(OLNode)); /*生成新结点*/
    			switch(CompareElement(pa->j,pb->j))
    			{
    			case -1:				/*如果A的列号小于B的列号,将矩阵A的当前元素值插入C*/
    				*pc=*pa; 
    				InsertMatrix(C,pc); 
    				pa=pa->right; 
    				break;
    			case  0:				/*如果矩阵A和B的列号相等,元素值相加*/
    				*pc=*pa; 
    				pc->e+=pb->e;
    				if(pc->e!=0)		/*如果和为非零,则将结点插入到C中*/
    					InsertMatrix(C,pc); 
    				else
    					free(pc); 
    				pa=pa->right; 
    				pb=pb->right;
    				break;
    			case  1:				/*如果A的列号大于B的列号,将矩阵B的当前元素值插入C中*/
    				*pc=*pb; 
    				InsertMatrix(C,pc); 
    				pb=pb->right; 
    			}
    		}
    		while(pa)					/*如果矩阵A还有未处理完的非零元素,则将剩余元素插入C中*/
    		{
    			pc=(OLink)malloc(sizeof(OLNode)); 
    			*pc=*pa;
    			InsertMatrix(C,pc); 
    			pa=pa->right; 
    		}
    		while(pb)					/*如果矩阵B还有未处理完的非零元素,则将剩余元素插入C中*/
    		{
    			pc=(OLink)malloc(sizeof(OLNode));
    			*pc=*pb; 
    			InsertMatrix(C,pc); 
    			pb=pb->right; 
    		}
    	}
    	if(C->len==0)					/*矩阵C的非零元素个数为零,则直接消耗C*/
    		DestroyMatrix(C);
    }
    void main(){
    	CrossList M,N,Q;
    	int row,col;
    	DataType value;
    	OLink p;
    	InitMatrix(&M);		/*初始化稀疏矩阵*/
    	CreateMatrix(&M);	/*创建稀疏矩阵*/
    	printf("矩阵M:
    ");
    	PrintMatrix(M);		/*以矩阵的形式输出稀疏矩阵*/
    
    	InitMatrix(&N);		/*初始化稀疏矩阵*/
    	CreateMatrix(&N);	/*创建稀疏矩阵*/
    	printf("矩阵N:
    ");
    	PrintMatrix(N);	/*以矩阵的形式输出稀疏矩阵*/
    	/*两个矩阵的相加*/
    	AddMatrix(M,N,&Q);
    	printf("两个稀疏矩阵相加结果:M+N=
    ");
    	PrintMatrix(Q);
    	/*在矩阵M中插入一个元素*/
    	printf("请输入要插入元素的行号、列号和元素值:");
    	scanf("%d,%d,%d",&row,&col,&value);
    	p=(OLNode*)malloc(sizeof(OLNode));
    	p->i=row;
    	p->j=col;
    	p->e=value;
    	InsertMatrix(&M,p);
    	printf("插入元素后,矩阵M:
    ");
    	PrintMatrix(M);
    	system("pause");
    }

  • 相关阅读:
    js 获取url参数
    new Date()日期在IOS的兼容问题
    js判断是否为微信浏览器
    ionic3 带数据返回上一页
    ionic3 打包android apk
    https打开有地图页面问题
    限制字符个数
    placeholder兼容ie
    Sequence Classification
    Part of Speech Tagging
  • 原文地址:https://www.cnblogs.com/javafly/p/6037143.html
Copyright © 2020-2023  润新知