Sparse Matrix (Orthogonal Linked List)

简单实现了稀疏矩阵的加法减法乘法和转置

Crosslist.h

#include <iostream>
using namespace std;

#define TRUE		1
#define FALSE		0
#define OK		1
#define ERROR		0
#define INFEASIBLE	-1
#define LOVERFLOW	-2	//避免与<math.h>中的定义冲突

typedef int Status;
typedef int ElemType;

class CrossList;	//类的提前声明
class OLNode {
    protected:
    	int      i, j;
    	ElemType e;
    	OLNode *right, *down;
    public:
    	friend istream& operator >> (istream &in, OLNode &n);		//输入一个OLNode型对象
    	friend ostream& operator << (ostream &out, const OLNode &n);	//输出一个OLNode型对象
    	friend class CrossList; //友元
    	friend istream& operator >> (istream &in, CrossList &m);	//取代CreateSMatrix功能,以三元组表的形式输入一个稀疏矩阵
    	friend ostream& operator << (ostream &out, const CrossList &m);	//取代PrintSMatrix,以矩阵形式输出
};

class CrossList {
    protected:
    	OLNode **rhead, **chead;    	int mu, nu, tu;
    public:
	/* 构造和析构函数 */
    	CrossList();							//增加的构造函数,对TSMatrix类的对象进行初始化
    	CrossList(const CrossList &m);					//增加的复制构造函数,完成TSMatrix类的对象的复制(三种调用时机)
    	~CrossList();							//取代DestroySMatrix
	/* cin/cout的重载 */
    	friend istream& operator >> (istream &in, CrossList &m);	//取代CreateSMatrix功能,以三元组表的形式输入一个稀疏矩阵
    	friend ostream& operator << (ostream &out, const CrossList &m);	//取代PrintSMatrix,以矩阵形式输出
	/* 成员函数形式的运算符重载 */
	CrossList& operator=(const CrossList  m);			//取代CopySMatrix,T=M表示把M矩阵复制到T中
	CrossList  operator+(const CrossList &m);			//和=重载一起,取代AddSMatrix, Q=M+N 表示求稀疏矩阵M+N的和
	CrossList  operator-(const CrossList &m);			//和=重载一起,取代SubSMatrix, Q=M-N 表示求稀疏矩阵M-N的差
	CrossList  operator*(const CrossList &m);			//和=重载一起,取代MultSMatrix,Q=M*N 表示求稀疏矩阵M*N的乘积
	CrossList  operator!();						//和=重载一起,取代TranspostSMatrix,!M 表示求M的转置矩阵
};

Crosslist.cpp

#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <string.h>
#include "Crosslist.h"
using namespace std;

istream &operator>>(istream &in, OLNode &n)
{
	return in;
}

ostream &operator<<(ostream &out, const OLNode &n)
{
	return out;
}

istream &operator>>(istream &in, CrossList &m)
{
	int i, j, k, mu, nu, tu;
	ElemType e;
	OLNode *p, *q;

	in >> mu >> nu >> tu;
	m.mu = mu;
	m.nu = nu;
	m.tu = tu;
	m.rhead = (OLNode**)malloc((mu + 1) * sizeof(OLNode*));
	m.chead = (OLNode**)malloc((nu + 1) * sizeof(OLNode*));

	for (k = 1; k <= mu; k++)
		m.rhead[k] = NULL;
	for (k = 1; k <= nu; k++)
		m.chead[k] = NULL;
	for (k = 0; k < tu; k++)
	{
		in >> i >> j >> e;
		i++; j++;
		p = (OLNode*)malloc(sizeof(OLNode));
		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->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; q = q->down);
			p->down = q->down;
			q->down = p;
		}
	}
	return in;
}

ostream &operator<<(ostream &out, const CrossList &m)
{
	int i, j, tot = 1;
	OLNode *p;
	int row[10001], col[10001], num[10001];
	for (j = 1; j <= m.mu; j++)
	{
		p = m.rhead[j];
		while (p)
		{
			row[tot] = p->i;
			col[tot] = p->j;
			num[tot] = p->e;
			p = p->right;
			tot++;
		}
	}

	for (i = 1; i <= m.mu; i++)
	{
		for (j = 1; j <= m.nu; j++)
		{
			bool flag = 0;
			for (int k = 1; k <= m.tu; k++)
				if (i == row[k] && j == col[k])
				{
					out << num[k] << " ";
					flag = 1;
					break;
				}
			if (flag == 0)
				out << 0 << " ";
		}
		out << endl;
	}
	return out;
}

CrossList::CrossList()
{
	rhead = chead = NULL;
	mu = nu = tu = 0;
}

CrossList::CrossList(const CrossList &m)
{
	int i;
	OLNode *p, *q = NULL, *q1 = NULL, *q2;
	mu = m.mu;
	nu = m.nu;
	tu = m.tu;
	rhead = (OLNode**)malloc((m.mu + 1) * sizeof(OLNode*));
	chead = (OLNode**)malloc((m.nu + 1) * sizeof(OLNode*));
	for (i = 1; i <= m.mu; i++)
		rhead[i] = NULL;
	for (i = 1; i <= m.nu; i++)
		chead[i] = NULL;
	for (i = 1; i <= m.mu; i++)
	{
		p = m.rhead[i];
		while (p)
		{
			q = (OLNode*)malloc(sizeof(OLNode));
			q->i = p->i;
			q->j = p->j;
			q->e = p->e;
			if (!rhead[i])
				rhead[i] = q1 = q;
			else
				q1 = q1->right = q;
			if (!chead[q->j])
			{
				chead[q->j] = q;
				q->down = NULL;
			}
			else
			{
				q2 = chead[q->j];
				while (q2->down)
					q2 = q2->down;
				q2->down = q;
				q->down = NULL;
			}
			p = p->right;
		}
		if (q)
			q->right = NULL;
	}
}

CrossList::~CrossList()
{
	int i;
	OLNode *p, *q;
	for (i = 1; i <= mu; i++)
	{
		p = *(rhead + i);
		while (p)
		{
			q = p;
			p = p->right;
			free(q);
		}
	}
	free(rhead);
	free(chead);
	rhead = chead = NULL;
	mu = nu = tu = 0;
}

CrossList &CrossList::operator=(const CrossList m)
{
	int i;
	OLNode *p, *q = NULL, *q1 = NULL, *q2;
	if (rhead)
	{
		for (i = 1; i <= mu; i++)
		{
			p = *(rhead + i);
			while (p)
			{
				q = p;
				p = p->right;
				free(q);
			}
		}
	}
	mu = m.mu;
	nu = m.nu;
	tu = m.tu;
	rhead = (OLNode**)malloc((m.mu + 1) * sizeof(OLNode*));
	chead = (OLNode**)malloc((m.nu + 1) * sizeof(OLNode*));
	for (i = 1; i <= m.mu; i++)
		rhead[i] = NULL;
	for (i = 1; i <= m.nu; i++)
		chead[i] = NULL;
	for (i = 1; i <= m.mu; i++)
	{
		p = m.rhead[i];
		while (p)
		{
			q = (OLNode*)malloc(sizeof(OLNode));
			q->i = p->i;
			q->j = p->j;
			q->e = p->e;
			if (!rhead[i])
				rhead[i] = q1 = q;
			else
				q1 = q1->right = q;
			if (!chead[q->j])
			{
				chead[q->j] = q;
				q->down = NULL;
			}
			else
			{
				q2 = chead[q->j];
				while (q2->down)
					q2 = q2->down;
				q2->down = q;
				q->down = NULL;
			}
			p = p->right;
		}
		if (q)
			q->right = NULL;
	}
	return *this;
}

CrossList CrossList::operator+(const CrossList &m)
{
	int i, k;
	OLNode *p, *pq = NULL, *pm, *pn;
	OLNode **col = NULL;
	CrossList Q;

	Q.mu = mu;
	Q.nu = nu;
	Q.tu = 0;
	Q.rhead = (OLNode**)malloc((Q.mu + 1) * sizeof(OLNode*));
	Q.chead = (OLNode**)malloc((Q.nu + 1) * sizeof(OLNode*));

	for (k = 1; k <= Q.mu; k++)
		Q.rhead[k] = NULL;
	for (k = 1; k <= Q.nu; k++)
		Q.chead[k] = NULL;
	col = (OLNode**)malloc((Q.nu + 1) * sizeof(OLNode*));

	for (k = 1; k <= Q.nu; k++)
		col[k] = NULL;
	for (i = 1; i <= mu; i++)
	{
		pm = rhead[i];
		pn = m.rhead[i];
		while (pm&&pn)
		{
			if (pm->j < pn->j)
			{
				p = (OLNode*)malloc(sizeof(OLNode));
				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)
			{
				p = (OLNode*)malloc(sizeof(OLNode));
				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 = (OLNode*)malloc(sizeof(OLNode));
				Q.tu++;
				p->i = i;
				p->j = pn->j;
				p->e = pm->e + pn->e;
				p->right = NULL;
				pm = pm->right;
				pn = pn->right;
			}
			else
			{
				pm = pm->right;
				pn = pn->right;
				continue;
			}
			if (Q.rhead[i] == NULL)
				Q.rhead[i] = pq = p;
			else
			{
				pq->right = p;
				pq = pq->right;
			}
			if (Q.chead[p->j] == NULL)
				Q.chead[p->j] = col[p->j] = p;
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
		while (pm)
		{
			p = (OLNode*)malloc(sizeof(OLNode));
			Q.tu++;
			p->i = i;
			p->j = pm->j;
			p->e = pm->e;
			p->right = NULL;
			pm = pm->right;
			if (Q.rhead[i] == NULL)
				Q.rhead[i] = pq = p;
			else
			{
				pq->right = p;
				pq = pq->right;
			}
			if (Q.chead[p->j] == NULL)
				Q.chead[p->j] = col[p->j] = p;
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
		while (pn)
		{
			p = (OLNode*)malloc(sizeof(OLNode));
			Q.tu++;
			p->i = i;
			p->j = pn->j;
			p->e = pn->e;
			p->right = NULL;
			pn = pn->right;
			if (Q.rhead[i] == NULL)
				Q.rhead[i] = pq = p;
			else
			{
				pq->right = p;
				pq = pq->right;
			}
			if (Q.chead[p->j] == NULL)
				Q.chead[p->j] = col[p->j] = p;
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
	}
	for (k = 1; k <= Q.nu; k++)
		if (col[k])
			col[k]->down = NULL;
	free(col);
	return Q;
}

CrossList CrossList::operator-(const CrossList &m)
{
	int i, k;
	OLNode *p, *pq = NULL, *pm, *pn;
	OLNode **col = NULL;
	CrossList Q;

	Q.mu = mu;
	Q.nu = nu;
	Q.tu = 0;
	Q.rhead = (OLNode**)malloc((Q.mu + 1) * sizeof(OLNode*));
	Q.chead = (OLNode**)malloc((Q.nu + 1) * sizeof(OLNode*));
	for (k = 1; k <= Q.mu; k++)
		Q.rhead[k] = NULL;
	for (k = 1; k <= Q.nu; k++)
		Q.chead[k] = NULL;
	col = (OLNode**)malloc((Q.nu + 1) * sizeof(OLNode*));
	for (k = 1; k <= Q.nu; k++)
		col[k] = NULL;
	for (i = 1; i <= mu; i++)
	{
		pm = rhead[i];
		pn = m.rhead[i];
		while (pm&&pn)
		{
			if (pm->j<pn->j)
			{
				p = (OLNode*)malloc(sizeof(OLNode));
				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)
			{
				p = (OLNode*)malloc(sizeof(OLNode));
				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 = (OLNode*)malloc(sizeof(OLNode));
				Q.tu++;
				p->i = i;
				p->j = pn->j;
				p->e = pm->e - pn->e;
				p->right = NULL;
				pm = pm->right;
				pn = pn->right;
			}
			else
			{
				pm = pm->right;
				pn = pn->right;
				continue;
			}
			if (Q.rhead[i] == NULL)
				Q.rhead[i] = pq = p;
			else
			{
				pq->right = p;
				pq = pq->right;
			}
			if (Q.chead[p->j] == NULL)
				Q.chead[p->j] = col[p->j] = p;
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
		while (pm)
		{
			p = (OLNode*)malloc(sizeof(OLNode));
			Q.tu++;
			p->i = i;
			p->j = pm->j;
			p->e = pm->e;
			p->right = NULL;
			pm = pm->right;
			if (Q.rhead[i] == NULL)
				Q.rhead[i] = pq = p;
			else
			{
				pq->right = p;
				pq = pq->right;
			}
			if (Q.chead[p->j] == NULL)
				Q.chead[p->j] = col[p->j] = p;
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
		while (pn)
		{
			p = (OLNode*)malloc(sizeof(OLNode));
			Q.tu++;
			p->i = i;
			p->j = pn->j;
			p->e = -pn->e;
			p->right = NULL;
			pn = pn->right;
			if (Q.rhead[i] == NULL)
				Q.rhead[i] = pq = p;
			else
			{
				pq->right = p;
				pq = pq->right;
			}
			if (Q.chead[p->j] == NULL)
				Q.chead[p->j] = col[p->j] = p;
			else
			{
				col[p->j]->down = p;
				col[p->j] = col[p->j]->down;
			}
		}
	}
	for (k = 1; k <= Q.nu; k++)
		if (col[k])
			col[k]->down = NULL;
	free(col);
	return Q;
}

CrossList CrossList::operator*(const CrossList &m)
{
	int i, j, e;
	OLNode *q, *p0, *q0, *q1=NULL, *q2;
	CrossList Q;
	Q.mu = mu;
	Q.nu = m.nu;
	Q.tu = 0;
	Q.rhead = (OLNode**)malloc((Q.mu + 1) * sizeof(OLNode*));
	Q.chead = (OLNode**)malloc((Q.nu + 1) * sizeof(OLNode*));
	for (i = 1; i <= Q.mu; i++)
		Q.rhead[i] = NULL;
	for (i = 1; i <= Q.nu; i++)
		Q.chead[i] = NULL;
	for (i = 1; i <= Q.mu; i++)
		for (j = 1; j <= Q.nu; j++)
		{
			p0 = rhead[i];
			q0 = m.chead[j];
			e = 0;
			while (p0&&q0)
			{
				if (q0->i<p0->j)
					q0 = q0->down;
				else if (q0->i>p0->j)
					p0 = p0->right;
				else
				{
					e += p0->e*q0->e;
					q0 = q0->down;
					p0 = p0->right;
				}
			}
			if (e)
			{
				Q.tu++;
				q = (OLNode*)malloc(sizeof(OLNode));
				q->i = i;
				q->j = j;
				q->e = e;
				q->right = NULL;
				q->down = NULL;
				if (!Q.rhead[i])
					Q.rhead[i] = q1 = q;
				else
					q1 = q1->right = q;
				if (!Q.chead[j])
					Q.chead[j] = q;
				else
				{
					q2 = Q.chead[j];
					while (q2->down)
						q2 = q2->down;
					q2->down = q;
				}
			}
		}
	return Q;
}

CrossList CrossList::operator!()
{
	int u, i;
	OLNode **head, *p, *q, *r;
	CrossList T = *this;
	u = mu;
	mu = nu;
	nu = u;
	head = rhead;
	rhead = chead;
	chead = head;
	for (u = 1; u <= mu; u++)
	{
		p = rhead[u];
		while (p)
		{
			q = p->down;
			i = p->i;
			p->i = p->j;
			p->j = i;
			r = p->down;
			p->down = p->right;
			p->right = r;
			p = q;
		}
	}
	return T;
}

 

Add a Comment

Your email address will not be published. Required fields are marked *