数组(矩阵)+ADT+代码实现

目录

表中的数据元素本身也是一个数据结构

数组

 ADT

矩阵的压缩存储

三元组顺序表

行逻辑链接的顺序表

稀疏矩阵的十字链表


表中的数据元素本身也是一个数据结构

数组

数组中的数据元素必须是同一数据类型

一个n维数组可以定义为其数据元素是n-1维数组类型的一维数组类型

二维数组任一元素a[ij]存储位置

从(0,0)开始存储:LOC(i,j) = LOC(0,0) + (b*i+j)L   

从(1,1)开始存储:LOC(i,j) = LOC(1,1) + LOC(b*(i-1)+j-1)L;

 ADT

ADT Array{
    数据元素:ji = 0,...,bi-1,  i = 1,2,...,n,
    数据关系:R = {R1,R2,...Rn}
    基本操作:
    InitArray(&A,n,bound1,bound2,...,boundn);
    操作结果:若维数n和各维长度合法,则构成相应的数组A,并返回OK;
    DestoryArray(&A);
    操作结果:销毁数组A
    Value(A,&e,index1,...,indexn);
    初始条件:A是n维数组,e为元素变量,随后是n个下标值;
    操作结果:若各下标不越界,则e赋值为所指定的A的元素值,并返回 OK;
    Assign(&A,e,index1,...,indexn);
    初始条件:A是n为数组,e为元素变量,随后是N个下标值
    操作结果:若下标不越界,则将e的值赋给所指定的A的元素,并返回OK;
}

矩阵的压缩存储

三元组顺序表

// 稀疏矩阵.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
# include<stdlib.h>

# define ElemType int
# define Status int
# define OK 1
# define ERROR 0
# define TRUE 1
# define FALSE 0
# define OVERFLOW -1
# define MAXSIZE 10
typedef struct
{
	int i, j;
	ElemType e;
}Triple;

typedef struct
{
	Triple data[MAXSIZE];
	int mu, nu, tu;//矩阵行数,列数,非零元素个数
}TSMatrix;

Status CreateSMatrix(TSMatrix *m)
{
	m = (TSMatrix *)malloc(1*sizeof(TSMatrix));

	if (!m)
	{
		printf("内存分配失败!\n");
		return TRUE;
	}

	m->mu = 0;
	m->nu = 0;
	m->tu = 0;

	return OK;
}

//销毁矩阵
Status DestorySMatrix(TSMatrix *m)
{
	if (!m)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	m->mu = 0;
	m->nu = 0;
	m->tu = 0;

	return OK;
}

//输入矩阵的值
Status InputM(TSMatrix *m)
{
	if (!m)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	int c;

	printf("输入矩阵的行数,列数,非零元素个数:\n");

	scanf_s("%d %d %d", &m->mu,&m->nu,&m->tu);

	printf("输入矩阵非零元素的值:\n");

	for (c = 1; c <= m->tu; c++)

	{

		scanf_s("%d", &m->data[c].i);

		scanf_s("%d", &m->data[c].j);

		scanf_s("%d", &m->data[c].e);

	}

	return OK;
}

//打印矩阵
Status PrintM(TSMatrix m)
{
	if (!(&m))
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	printf("输出矩阵:\n");

	int i, j;

	int t = 1;
	for (i = 1; i <= m.mu; ++i)
	{
		for (j = 1; j <= m.nu; ++j)
		{
			//非零元素
			if (m.data[t].i == i && m.data[t].j == j)
				printf("%d ",m.data[t++].e);
			//零元素
			else
				printf("0 ");
		}
		printf("\n");
	}

	return OK;
}

//复制矩阵
Status CopySMatrix(TSMatrix m, TSMatrix *t)
{
	if (!&m)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	t->nu = m.nu;
	t->mu = m.mu;
	t->tu = m.tu;

	int i;
	for (i = 1; i <= m.tu; ++i)
	{
		t->data[i].i = m.data[i].i;
		t->data[i].j = m.data[i].j;
		t->data[i].e = m.data[i].e;
	}

	return OK;
}

//普通转置矩阵
Status TransposeSMatrix(TSMatrix m,TSMatrix *t)
{
	//普通转置,从列开始遍历,列数等于矩阵元素列时,进行转置,非零元素累加
	if (!&m)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	if (!t)
	{
		printf("内存分配失败!\n");
		exit(OVERFLOW);
	}

	t->mu = m.nu;
	t->nu = m.mu;
	t->tu = m.tu;
	if (t->tu)
	{
		int i = 1, j;//记录非零元素的个数

		for (j = 1; j <= t->nu; ++j)
		{
			for (i = 1; i <= m.tu; ++i)
			{
				if (m.data[i].j == j)
				{
					t->data[i].i = m.data[i].j;
					t->data[i].j = m.data[i].i;
					t->data[i].e = m.data[i].e;
					i++;
				}
			}
		}
	}
	
	return OK;
}

//快速转置
Status FastTranposeSMatrix(TSMatrix m, TSMatrix *T)
{
	T->mu = m.mu;
	T->nu = m.nu;
	T->tu = m.tu;
	int col = 1,t,q;
	int num[MAXSIZE], cpot[MAXSIZE];

	if (T->tu)
	{
		//初始化计数数组
		for (col = 1; col <= m.nu; ++col)
			num[col] = 0;
		for (t = 1; t <= m.tu; ++t)
			++num[m.data[t].j];//求m中每一列含非零元个数
		cpot[1] = 1;
		//求第cpot列中第一个非零元在b.data中的序列
		for (col = 2; col <= m.nu; ++col)
			cpot[col] = cpot[col - 1] + num[col - 1];

		for (t = 1; t <= m.tu; ++t)
		{
			col = m.data[t].j;
			q = cpot[col];
			T->data[q].i = m.data[t].j;
			T->data[q].j = m.data[t].i;
			T->data[q].e = m.data[t].e;
			++cpot[col];
		}
	}
	else
	{
		return ERROR;
	}

	return OK;
}

int main()
{
	TSMatrix t;
	TSMatrix m;

	CreateSMatrix(&t);
	InputM(&t);
	PrintM(t);
	FastTranposeSMatrix(t, &m);
	PrintM(m);

	/*
	TransposeSMatrix(t, &m);
	PrintM(m);
	*/
    return 0;
}

行逻辑链接的顺序表

// 稀疏矩阵行逻辑链接顺序表.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
# include<stdlib.h>

# define Status int
# define ElemType int
# define OK 1
# define ERROR 0
# define OVERFLOW -1
# define TRUE 1
# define FALSE 0
# define MAXSIZE 10
# define MAXRC 10

typedef struct
{
	ElemType e;
	int i, j;
}Triple;

typedef struct
{
	Triple data[MAXSIZE+1];
	int rpos[MAXRC + 1];//各行第一个非零元素的位置表
	int mu, nu, tu;//存储行数,列数,非零元个数
}RLSMatrix;

//创建矩阵
Status CreateSMatrix(RLSMatrix *m)
{
	int i;
	Status k;
	Triple T;
	
	printf("请输入矩阵的行数,列数 ,非零元素数:\n");
	scanf_s("%d%d%d",&m->mu,&m->nu,&m->tu);

	m->data[0].i = 0;//为验证输入是否按照非递减序 比较最准备
	for (i = 1; i <= m->tu; ++i)
	{
		printf("按顺序输入第%d个非零元素所在行(1~%d),列(1~%d),元素值:", i, m->mu, m->nu);

		do {
			printf("输入三元组行,列,值\n");
			scanf_s("%d%d%d",&T.i,&T.j,&T.e);
			k = 0;

			if (T.i < 1 || T.i > m->mu || T.j < 1 || T.j > m->nu)
			{
				printf("行或者列超出范围!\n");
				k = 1;
				return ERROR;
			}
			if (T.i <= m->data[i - 1].i && T.j <= m->data[i - 1].j)
			{
				printf("没有按顺序输入非零元素!\n");
				return ERROR;
				k = 1;
			}
		} while (k);

		m->data[i] = T;
	}

	for (i = 1; i <= m->tu; i++) // 计算rpos[]
		if (m->data[i].i > m->data[i - 1].i)
			for (T.i = 0; T.i < m->data[i].i - m->data[i - 1].i; T.i++)
				m->rpos[m->data[i].i - T.i] = i;

	for (i = m->data[m->tu].i + 1; i <= m->mu; i++) // 给最后没有非零元素的几行赋值
		m->rpos[i] = m->tu + 1;

	return OK;
}

//销毁矩阵
Status DestorySMatrix(RLSMatrix *m)
{
	if (!m)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	m->mu = 0;
	m->nu = 0;
	m->tu = 0;

	return OK;
}

//输出矩阵
Status PrintM(RLSMatrix m)
{
	if (!(&m))
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	printf("输出矩阵:\n");

	int i, j;

	int t = 1;
	for (i = 1; i <= m.mu; ++i)
	{
		for (j = 1; j <= m.nu; ++j)
		{
			//非零元素
			if (m.data[t].i == i && m.data[t].j == j)
				printf("%d ", m.data[t++].e);
			//零元素
			else
				printf("0 ");
		}
		printf("\n");
	}

	return OK;
}

//复制矩阵
Status CopySMatrix(RLSMatrix m, RLSMatrix *t)
{
	if (!&m)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	t->nu = m.nu;
	t->mu = m.mu;
	t->tu = m.tu;

	int i;
	for (i = 1; i <= m.tu; ++i)
	{
		t->data[i].i = m.data[i].i;
		t->data[i].j = m.data[i].j;
		t->data[i].e = m.data[i].e;
		t->rpos[i] = m.rpos[i];
	}

	return OK;
}

//快速转置
Status TransposeSMatrix(RLSMatrix m, RLSMatrix *T)
{
	T->mu = m.mu;
	T->nu = m.nu;
	T->tu = m.tu;
	int col = 1, t, q;
	int num[MAXSIZE], cpot[MAXSIZE];

	if (T->tu)
	{
		//初始化计数数组
		for (col = 1; col <= m.nu; ++col)
			num[col] = 0;
		for (t = 1; t <= m.tu; ++t)
			++num[m.data[t].j];//求m中每一列含非零元个数
		cpot[1] = 1;
		//求第cpot列中第一个非零元在b.data中的序列
		for (col = 2; col <= m.nu; ++col)
			cpot[col] = cpot[col - 1] + num[col - 1];

		for (t = 1; t <= m.tu; ++t)
		{
			col = m.data[t].j;
			q = cpot[col];
			T->data[q].i = m.data[t].j;
			T->data[q].j = m.data[t].i;
			T->data[q].e = m.data[t].e;
			++cpot[col];
		}
	}
	else
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	return OK;
}

//矩阵相乘
Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)
{
	int arow, brow, p, q, ccol, ctemp[MAXRC + 1];

	if (M.nu != N.mu) // 矩阵M的列数应和矩阵N的行数相等

		return ERROR;

	Q->mu = M.mu; // Q初始化

	Q->nu = N.nu;

	Q->tu = 0;

	M.rpos[M.mu + 1] = M.tu + 1; // 为方便后面的while循环临时设置

	N.rpos[N.mu + 1] = N.tu + 1;

	if (M.tu*N.tu != 0) // M和N都是非零矩阵
	{
		for (arow = 1; arow <= M.mu; ++arow)
		{ //从M的第一行开始,到最后一行,arow是M的当前行
			for (ccol = 1; ccol <= Q->nu; ++ccol)
				ctemp[ccol] = 0; //Q的当前行的各列元素累加器清零

			Q->rpos[arow] = Q->tu + 1; //Q当前行的第1个元素位于上1行最后1个元素之后
			
			/*找到每一行中的非零元素*/
			for (p = M.rpos[arow]; p<M.rpos[arow + 1]; ++p)
			{ // 对M当前行中每一个非零元
				brow = M.data[p].j; //找到对应元在N中的行号(M当前元的列号)
				/*
				rpos[row]指示矩阵N的第row行中第一个非零元在N.data中的序号,rpos[row+1]-1指向的第row行最后一个非零元的位置
				*/
				for (q = N.rpos[brow]; q<N.rpos[brow + 1]; ++q)
				{
					ccol = N.data[q].j; //乘积元素在Q中列号
					ctemp[ccol] += M.data[p].e*N.data[q].e;
				}//for
			} //求得Q中第arow行的非零元

			for (ccol = 1; ccol <= Q->nu; ++ccol) //压缩存储该行非零元
				if (ctemp[ccol])
				{
					if (++Q->tu>MAXSIZE)
						return ERROR;

					Q->data[Q->tu].i = arow;
					Q->data[Q->tu].j = ccol;
					Q->data[Q->tu].e = ctemp[ccol];
				}//if
		}//for
	}//if

	return OK;
}

int main()
{
	RLSMatrix m,t,q;
	
	CreateSMatrix(&m);
	CopySMatrix(m, &t);
	PrintM(m);
	PrintM(t);
	MultSMatrix(m, t, &q);
	PrintM(q);

    return 0;
}

稀疏矩阵的十字链表

// 稀疏矩阵的十字链表.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
# include<stdlib.h>

# define ElemType int
# define Status int
# define OK 1
# define ERROR 0
# define OVERFLOW -1
# define TRUE 1
# define FALSE 0
# define MAXSIZE 10


typedef struct OLNode
{
	int i, j;
	ElemType e;
	struct OLNode *right, *down;
}OLNode,*OLink;

typedef struct
{
	OLink *rhead, *chead;//行和列链表头指针向量基址
	int mu, nu, tu;//稀疏矩阵的行数、列数和非零元素个数
}CrossList;

//创建稀疏矩阵,采用十字链表存储表示
Status CreateSMatrix(CrossList *M)
{
	OLNode *p,*q;
	int m, n, t,i,j,e;
	printf("输入矩阵行数、列数、非零元个数:\n");
	scanf_s("%d%d%d",&m,&n,&t);//输入行数列数和非零元个数

	M->mu = m; M->nu = n; M->tu = t;
	if (!(M->rhead = (OLink*)malloc((m + 1) * sizeof(OLink))))
	{
		printf("内存分配失败!\n");
		exit(OVERFLOW);
	}
	if (!(M->chead = (OLink*)malloc((n + 1) * sizeof(OLink))))
	{
		printf("内存分配失败!\n");
		exit(OVERFLOW);
	}

	for (i = 1; i <= m; ++i)
	{
		M->chead[i] = NULL;//初始化行列头指针向量;各行列链表为空链表
		M->rhead[i] = NULL;
	}
		

	while (1)
	{
		printf("输入点的坐标及其值:\n");
		scanf_s("%d",&i);

		if (i == 0)
		{
			printf("输入结束!\n");
			break;//以0作为输入结束标志
		}
		scanf_s("%d%d",&j,&e);
		//分配新节点
		if (!(p = (OLNode *)malloc(1 * sizeof(OLNode))))
		{
			printf("节点内存分配失败!\n");
			exit(OVERFLOW);
		}

		p->i = i; p->j = j; p->e = e;//赋值

		//行插入
		if (M->rhead[i] == NULL || M->rhead[i]->j > j)
		{
			//覆盖否指针节点,若该行没有元素或者第一个元素在该节点之后,将p赋值给头结点
			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->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[j].i < i; q = q->down);

			p->down = q->down;
			q->down = p;
		}
	}

	return OK;
}

//销毁十字链表
Status DestroySMatrix(CrossList *M)
{
	int i = 1;
	OLNode *p, *q;

	for (i = 1; i <= (*M).mu; ++i)
	{
		p = M->rhead[i];//遍历指针
		while (p)
		{
			q = p;
			p = p->right;
			free(q);//Q指向被释放内存的地址
		}
	}

	
	M->chead = M->rhead = NULL;
	M->mu = M->nu = M->tu = 0;

	return OK;
}

//访问函数
Status visit(ElemType e)
{
	printf("%d ",e);
	return OK;
}

//输出十字链表表示的矩阵
Status TraverseM(CrossList M,Status(*visit)(ElemType e))
{
	if (!(&M))
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	printf("输出矩阵:\n");

	int i, j;
	int t = 1;
	OLNode* p;
	for (i = 1; i <= M.mu; ++i)
	{
		p = M.rhead[i];
		if(p)
		{
			for (j = 1; j <= M.nu; ++j)
			{
				//非零元素
				if (p && p->j == j)
				{
					visit(p->e);
					p = p->right;
				}
				else
				{
					visit(0);
				}
			}
		}
		else
		{
			for (j = 1; j <= M.nu; ++j)
			{
				printf("0 ");
			}
		}
		printf("\n");
	}

	return OK;
}

//输出十字链表存储的值
Status DisplayM(CrossList M)
{
	if (!(&M))
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	printf("按行输出十字链表存储的值是:\n");
	int k;
	OLink p;
	for (k = 1; k <= M.mu; ++k)
	{
		p = M.rhead[k];
		while (p)
		{
			printf("(%d,%d) e = %d",p->i,p->j,p->e);
			p = p->right;
			printf("\n");
		}
	}

	return OK;
}

//复制矩阵
Status CopyM(CrossList M, CrossList *T)
{
	if (!M.rhead)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	if ((T->rhead))
		DestroySMatrix(T);

	int i;
	OLNode *p, *q = NULL, *qr = NULL, *qc = NULL;

	T->mu = M.mu; T->nu = M.nu; T->tu = M.tu;
	T->rhead = (OLink *)malloc((T->mu + 1) * sizeof(OLink));
	T->chead = (OLink *)malloc((T->nu + 1) * sizeof(OLink));
	if (!T->chead || !T->rhead)
	{
		printf("内存分配失败!\n");
		exit(OVERFLOW);
	}

	for (i = 1; i <= M.mu; i++) // 初始化矩阵T的行头指针向量;各行链表为空链表 
		(*T).rhead[i] = NULL;
	for (i = 1; i <= M.nu; i++) // 初始化矩阵T的列头指针向量;各列链表为空链表 
		(*T).chead[i] = NULL;

	
	for (i = 1; i <= M.mu; ++i)
	{
		p = M.rhead[i];
		while (p)
		{
			//因为创建链表时,已经确定其位置,所以只有两种情况
			//1、第一个位置  2、链表尾部
			q = (OLNode *)malloc(1 * sizeof(OLNode));
			if (!q)
			{
				printf("内存分配失败!\n");
				exit(OVERFLOW);
			}

			q->i = p->i;
			q->j = p->j;
			q->e = p->e;

			if (!T->rhead[i])//插在表头
			{
				T->rhead[i] = q;
				qr = q;//指向队尾
			}
			else//表尾
			{
				qr->right = q;
				qr = q;
			}

			if (!T->chead[q->j])//表头
			{
				T->chead[q->j] = q;
				q->down = NULL;
			}
			else
			{
				qc = T->chead[q->j];
				while (qc->down)
				{
					qc = qc->down;
				}
				qc->down = q;
				q->down = NULL;
			}

			p = p->right;
		}

		q->right = NULL;
	}

	return OK;
}

//矩阵取反
Status NegateM(CrossList M, CrossList *T)
{
	if (!M.rhead)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	if ((T->rhead))
		DestroySMatrix(T);

	int i;
	OLNode *p, *q = NULL, *qr = NULL, *qc = NULL;

	T->mu = M.mu; T->nu = M.nu; T->tu = M.tu;
	T->rhead = (OLink *)malloc((T->mu + 1) * sizeof(OLink));
	T->chead = (OLink *)malloc((T->nu + 1) * sizeof(OLink));
	if (!T->chead || !T->rhead)
	{
		printf("内存分配失败!\n");
		exit(OVERFLOW);
	}

	for (i = 1; i <= M.mu; i++) // 初始化矩阵T的行头指针向量;各行链表为空链表 
		(*T).rhead[i] = NULL;
	for (i = 1; i <= M.nu; i++) // 初始化矩阵T的列头指针向量;各列链表为空链表 
		(*T).chead[i] = NULL;


	for (i = 1; i <= M.mu; ++i)
	{
		p = M.rhead[i];
		while (p)
		{
			//因为创建链表时,已经确定其位置,所以只有两种情况
			//1、第一个位置  2、链表尾部
			q = (OLNode *)malloc(1 * sizeof(OLNode));
			if (!q)
			{
				printf("内存分配失败!\n");
				exit(OVERFLOW);
			}

			q->i = p->i;
			q->j = p->j;
			q->e = -1 * p->e;

			if (!T->rhead[i])//插在表头
			{
				T->rhead[i] = q;
				qr = q;//指向队尾
			}
			else//表尾
			{
				qr->right = q;
				qr = q;
			}

			if (!T->chead[q->j])//表头
			{
				T->chead[q->j] = q;
				q->down = NULL;
			}
			else
			{
				qc = T->chead[q->j];
				while (qc->down)
				{
					qc = qc->down;
				}
				qc->down = q;
				q->down = NULL;
			}

			p = p->right;
		}

		q->right = NULL;
	}

	return OK;
}

//矩阵相加 Q = M+N
Status AddSMatrix(CrossList M, CrossList N, CrossList *Q)
{
	if (!M.chead || !N.chead)//矩阵不存在的情况
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	if (M.mu != N.mu || M.nu != N.nu)//同类型矩阵相加
	{
		printf("两个矩阵不是同一个类型矩阵!\n");
		return ERROR;
	}

	int k, i;
	OLink *col;
	OLNode *pm, *pn, *pq = NULL, *p;

	Q->mu = M.mu; Q->nu = M.nu; Q->tu =0;//初始化变量
	Q->rhead = (OLink *)malloc((Q->mu + 1)*sizeof(OLink));//按行存储非零元素的地址
	Q->chead = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));//按列存储非零元素地址
	col = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));//存储每一列的最后一个非零元素地址
	if (!Q->rhead || !Q->chead || !col)
	{
		printf("内存分配失败!\n");
		return ERROR;
	}
	
	//使用指针必须初始化
	for (k = 1; k <= Q->mu; ++k)
	{
		Q->rhead[k] = NULL;
	}
	for (k = 1; k <= Q->nu; ++k)
	{
		col[k] = NULL;
		Q->chead[k] = NULL;
	}
	//遍历行
	/*
	每行矩阵相加有四种结果
	1.M矩阵元素不为0,N矩阵元素为0,
	2.M矩阵为0,N矩阵不为0
	3.M矩阵与N矩阵相加不为0
	4.相加为0
	*/
	for (i = 1; i <= M.mu; ++i)
	{
		pm = M.rhead[i];
		pn = N.rhead[i];
		while (pm && pn)
		{
			//注意循环条件是M矩阵和N矩阵元素都不为零,所以一旦有一个行元素为到头,则退出;
			//所以需要分别将MN中剩余的元素插入矩阵Q中
			if (pm->j < pn->j)//第一种情况,该行M元素不为0,N矩阵元素为0
			{
				p = (OLink)malloc(sizeof(OLNode));
				if (!p)
				{
					printf("内存分配失败!\n");
					exit(OVERFLOW);
				}
				Q->tu++;
				p->i = i;
				p->j = pm->j;
				p->e = pm->e;
				p->right = NULL;
				pm = pm->right;
			}
			else if (pm->j > pn->j)//第二种情况,N矩阵不为0,M矩阵为0
			{
				p = (OLink)malloc(sizeof(OLNode));
				if (!p)
				{
					printf("内存分配失败!\n");
					exit(OVERFLOW);
				}
				Q->tu++;
				p->i = i;
				p->j = pn->j;
				p->e = pn->e;
				p->right = NULL;
				pn = pn->right;
			}
			else if (pm->e + pn->e)
			{
				p = (OLink)malloc(sizeof(OLNode));
				if (!p)
				{
					printf("内存分配失败!\n");
					return ERROR;
				}
				Q->tu++;
				p->e = pm->e + pn->e;
				p->i = i;
				p->j = pm->j;
				p->right = NULL;
				pm = pm->right;
				pn = pn->right;
			}
			else
			{
				pm = pm->right;
				pn = pn->right;
				continue;
			}
			//前三种情况的共同操作是将p指向的元素插入到矩阵Q中,类似与创建矩阵
			if (!Q->rhead[i])
			{
				Q->rhead[i] = p;
				pq = p;
			}
			else
			{
				pq->right = p;
				pq = p;
			}
			if (!Q->chead[p->j])
			{
				Q->chead[p->j] = p;
				col[p->j] = p;//col指向该列的最后一个元素
			}
			else
			{//在列尾插入,并修改列尾指针的指向
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}//while(遍历行内)
		//插入M矩阵剩余元素
		while (pm)
		{
			p = (OLink)malloc(sizeof(OLNode));
			if (!p)
			{
				printf("内存分配失败!\n");
				exit(OVERFLOW);
			}
			Q->tu++;
			p->i = i;
			p->j = pm->j;
			p->e = pm->e;
			p->right = NULL;
			pm = pm->right;
			if (!Q->rhead[i])
			{
				Q->rhead[i] = p;
				pq = p;
			}
			else
			{
				pq->right = p;
				pq = p;
			}
			if (!Q->chead[p->j])
			{
				Q->chead[p->j] = p;
				col[p->j] = p;
			}
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
		//插入N矩阵剩余元素
		while (pn)
		{
			p = (OLink)malloc(sizeof(OLNode));
			if (!p)
			{
				printf("内存分配失败!\n");
				exit(OVERFLOW);
			}
			Q->tu++;
			p->i = i;
			p->j = pn->j;
			p->e = pn->e;
			p->right = NULL;
			pn = pn->right;
			if (!Q->rhead[i])
			{
				Q->rhead[i] = p;
				pq = p;
			}
			else
			{
				pq->right = p;
				pq = p;
			}
			if (!Q->chead[p->j])
			{
				Q->chead[p->j] = p;
				col[p->j] = p;
			}
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
	}//for(遍历每行)
	//将每一列最后一个元素的列down指针赋值
	for (k = 1; k <= Q->nu; ++k)
	{
		if (col[k])
		{
			col[k]->down = NULL;
		}
	}

	return OK;
}

//矩阵相减Q = M-N
Status SubtSMatrix(CrossList M, CrossList N, CrossList *Q)
{
	if (!M.chead || !N.chead)
	{
		printf("矩阵不存在!\n");
		return ERROR;
	}

	if (M.mu != N.mu || M.nu != N.nu)
	{
		printf("矩阵类型不一致!\n");
		return ERROR;
	}

	CrossList tmp;
	//矩阵取反
	NegateM(N,&tmp);
	AddSMatrix(M, tmp, Q);

	return OK;
}

//矩阵乘积 Q = M*N
Status MultiSM(CrossList M, CrossList N, CrossList *Q)
{
	if (!M.chead || !N.rhead)
	{//矩阵不存在
		printf("矩阵不存在!\n");
		return ERROR;
	}

	if (M.mu != N.nu)
	{//M矩阵行数不等于列数,不能相乘
		printf("M矩阵行不等于N的列数,不能相乘!\n");
		return ERROR;
	}

	if (Q->rhead)
		DestroySMatrix(Q);
	int i, k,j;
	ElemType e;
	OLink p0, q0, q, q1 = NULL, q2 = NULL;

	//初始化
	Q->mu = M.mu; Q->nu = N.nu; Q->tu = 0;
	Q->chead = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));
	Q->rhead = (OLink *)malloc((Q->nu + 1) * sizeof(OLink));
	if (!Q->rhead || !Q->chead)
	{
		printf("内存分配失败!\n");
		return ERROR;
	}
	//初始化指针
	for (k = 1; k <= Q->mu; ++k)
	{
		Q->rhead[k] = NULL;
	}
	for (k = 1; k <= Q->nu; ++k)
	{
		Q->chead[k] = NULL;
	}

	for (i = 1; i <= Q->mu; ++i)
	{
		for (j = 1; j <= Q->nu; ++j)
		{
			p0 = M.rhead[i];//p0指向M中行元
			q0 = N.chead[j];//q0指向q中列元
			e = 0;
			while (p0 && q0)
			{
				if (q0->i < p0->j)//q0所在行小于p0所在列
				{
					q0 = q0->down;
				}
				else if (q0->i > p0->j)//q0所在行小于p0所在列
				{
					p0 = p0->right;
				}
				else//两元素可以相乘
				{
					e += p0->e * q0->e;
					p0 = p0->right;
					q0 = q0->down;
				}
			}

			if (e)//乘积不为0可以插入矩阵
			{
				Q->tu++;
				q = (OLink)malloc(sizeof(OLNode));
				if (!q)
				{
					printf("内存分配失败!\n");
					exit(OVERFLOW);
				}
				q->i = i;
				q->j = j;
				q->e = e;
				q->right = NULL;
				q->right = NULL;
				
				//行插入
				if (!Q->rhead[i])
				{
					Q->rhead[i] = q;
					q1 = q;
				}
				else
				{
					q1->right = q;
					q1 = q;
				}

				//列插入
				if (!Q->chead[j])
				{
					Q->chead[j] = q;
				}
				else
				{
					q2 = Q->chead[j];
					while (q2->down)
					{
						q2 = q2->down;
					}

					q2->down = q;
				}
			}//while
		}//for_j
	}//for_i

	return OK;
}

int main()
{
	CrossList m,t,n;

	printf("输入矩阵m:\n");
	CreateSMatrix(&m);
	TraverseM(m,visit);

	printf("输入矩阵n:\n");
	CreateSMatrix(&n);
	TraverseM(n, visit);
	/*
	MultiSM(m, n, &t);
	TraverseM(t,visit)
	SubtSMatrix(m, n, &t);
	TraverseM(t,visit);
	AddSMatrix(m, n, &t);
	TraverseM(t, visit);
	*/
	return 0;
}

参考链接:

https://www.cnblogs.com/mycapple/archive/2012/08/03/2620932.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AmosTian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值