C++实现稀疏矩阵的十字链表表示法

本文详细介绍了如何使用C++实现稀疏矩阵的十字链表表示法,包括矩阵的初始化、插入元素、删除元素和矩阵运算等操作。通过这种方法,可以高效地处理大量为零的元素,降低存储开销并提升计算效率。
摘要由CSDN通过智能技术生成

/*
 * OLMat.h
 *
 *  Created on: Oct 17, 2015
 *      Author: chris
 */

#ifndef OLMAT_H_
#define OLMAT_H_

#include<iostream>

typedef int ElemType;

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

	OLNode():i(0), j(0),
			right(NULL), down(NULL) {}
};

struct OLMat{
	OLNode *rhead, *chead;
	int mu, nu, tu;

	OLMat(): rhead(NULL), chead(NULL),
			mu(0), nu(0), tu(0) {}
};

bool OLMatCreate(OLMat & mat, int nrows, int ncols);
void OLMatDestroy(OLMat & mat);

bool OLMatPutVal(OLMat & mat, int i, int j, ElemType e);
bool OLMatGetVal(OLMat & mat, int i, int j, ElemType& e);
bool OLMatDelEnt(OLMat & mat, int i, int j);

bool OLMatInput(OLMat & mat);
void OLMatPrint(OLMat & mat);

void OLMatTranspose(OLMat & mat);

#endif /* OLMAT_H_ */



/*
 * OLMat.cpp
 *
 *  Created on: Oct 17, 2015
 *      Author: chris
 */

#include"OLMat.h"
#include<iostream>

using namespace std;

bool OLMatCreate(OLMat & mat, int nrows, int ncols)
{
	mat.rhead = new OLNode[nrows];
	if(!mat.rhead) return false;

	mat.chead = new OLNode[ncols];
	if(!mat.chead) {
        delete mat.rhead;
		return false;
	}

	mat.mu = nrows;
	mat.nu = ncols;
	mat.tu = 0;
	return true;
}

void OLMatDestroy(OLMat & mat)
{
	for(int i = 0; i < mat.mu; ++i) {
		OLNode * rprior = mat.rhead+i;
		while(rprior->right) {
			OLNode * pcur = rprior->right;
			rprior->right = pcur->right;
			delete pcur;
		}//endw
	}//endf

	delete mat.rhead;
	delete mat.chead;
	mat.mu = mat.nu = mat.tu = 0;
}

bool OLMatPutVal(OLMat & mat, int i, int j, ElemType e)
{
	if(i < 0 || i >= mat.mu || j < 0 || j >= mat.nu) {
		cerr << "Index out of bound." << endl;
		return false;
	}

	//find pos.
	OLNode *rprior = mat.rhead+i;
	while(rprior->right && rprior->right->j < j)
		rprior = rprior->right;

	if(rprior->right && rprior->right->j == j) {
		rprior->right->e = e;
	}
	else
	{
		OLNode *pcur = new OLNode;
		if(!pcur) return false;

		//ins row
		pcur->i = i; pcur->j = j; pcur->e = e;
		pcur->right = rprior->right;
		rprior->right = pcur;
		++mat.tu;

		//ins col
		OLNode* cprior = mat.chead+j;
		while(cprior->down && cprior->down->i < i)
			cprior = cprior->down;
		pcur->down = cprior->down;
		cprior->down = pcur;
	} //endif

	return true;
}

bool OLMatGetVal(OLMat & mat, int i, int j, ElemType& e)
{
	if(i < 0 || i >= mat.mu || j < 0 || j >= mat.nu) {
		cerr << "Index out of bound." << endl;
		return false;
	}

	e = 0;    // default value.
	OLNode *pcur = mat.rhead[i].right;
	while(pcur && pcur->j < j)
		pcur = pcur->right;

	if(pcur && pcur->j == j)
		e = pcur->e;
    return true;
}

bool OLMatDelEnt(OLMat & mat, int i, int j)
{
	if(i < 0 || i >= mat.mu || j < 0 || j >= mat.nu)
		return false;

	OLNode * rprior = mat.rhead+i;
	while(rprior->right && rprior->right->j < j)
		rprior = rprior->right;

	if(rprior->right && rprior->right->j == j) {
		OLNode * pcur = rprior->right;
		rprior->right = pcur->right;

		OLNode * cprior = mat.chead + j;
		while(cprior->down != pcur)
			cprior = cprior->down;

		cprior->down = pcur->down;
		delete pcur;
		--mat.tu;

		return true;
	}
	return false;
}

bool OLMatInput(OLMat & mat)
{
	cout << "Input a "
			<< mat.mu << " x " << mat.nu
			<< " matrix: " << endl;
	int n;
	cout << "Number of nonzeros: ";
	cin >> n;

	cout << "Input row, col, val: " << endl;
	int row, col;
	ElemType e;
	for(int i = 0; i < n; ++i) {
		cin >> row >> col >> e;
		if(!OLMatPutVal(mat, row, col, e))
			return false;
	}
	return true;
}

void OLMatPrint(OLMat & mat)
{
	for(int i = 0; i < mat.mu; ++i) {
		OLNode * pcur = mat.rhead[i].right;
		int nextj = 0;
		while(pcur) {
			while(nextj != pcur->j) {
				cout << "0 ";
				++nextj;
			} //endw
			cout << pcur->e << " ";
			pcur = pcur->right;
			++nextj;
		}//endw

		while(nextj != mat.nu) {
			cout << "0 ";
			++nextj;
		}

		cout << endl;
	} // endf
}

void OLMatTranspose(OLMat & mat)
{
	for(int i = 0; i < mat.mu; ++i) {
		OLNode* rprior = mat.rhead+i;
		while(rprior) {
			OLNode * rnext = rprior->right;

			//swap i, j
			int t = rprior->i;
			rprior->i = rprior->j;
			rprior->j = t;
			//swap right, down
			OLNode * tp = rprior->right;
			rprior->right = rprior->down;
			rprior->down = tp;

			rprior = rnext;
		}
	}//endf

	for(int j = 0; j < mat.nu; ++j)
		mat.chead[j].right = mat.chead[j].down;

	int t = mat.mu;
	mat.mu = mat.nu;
	mat.nu = t;

	OLNode* tp = mat.rhead;
	mat.rhead = mat.chead;
	mat.chead = tp;
}




/*
 * Main.cpp
 *
 *  Created on: Oct 12, 2015
 *      Author: chris
 */

#include<iostream>
#include"OLMat.h"

using namespace std;

int main(void)
{
	OLMat mat;
	int r, c;
	cout << "nrows, ncols: " << endl;
	cin >> r >> c;
	OLMatCreate(mat, r, c);

	int n;
	cout << "num of nonzeros: " << endl;
	cin >> n;

	cout << "i, j, e: " << endl;
	for(int i = 0; i < n; ++i) {
		ElemType e;
		cin >> r >> c >> e;
		if(!OLMatPutVal(mat, r, c, e))
			cout << "input failed." << endl;
	}//endf

	OLMatPrint(mat);
	cout << endl;

	OLMatTranspose(mat);

	OLMatPrint(mat);
	cout << endl;

	OLMatDestroy(mat);
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值