/*
* 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;
}