您的位置:首页 > 编程语言 > C语言/C++

稀疏矩阵的实现(三元组存储)C++

2015-11-17 15:33 621 查看
通过三元组存储稀疏矩阵,压缩存储空间

/*
稀疏矩阵的实现
*/
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
//存储域
const int MAX_N = 100;
class elem_node
{
public:
int elem_row;//元素行号
int elem_col;//元素列号
int elem_value;//元素值
};

class Node
{
public:
int total_row;//总行数
int total_col;//总列数
int total_num;//非0元素总数
elem_node data[MAX_N];//非0元素数组
};

class Matrix
{
public:
Matrix(){}
~Matrix(){}
//构建稀疏矩阵三元组
void CreateMat(string filename, int rows, int cols)
{
int i, j;
int fdata;
ifstream readFile;
mat.total_num = 0;
mat.total_col = cols;//总行数
mat.total_row = rows;//总列数
readFile.open(filename);
//打开错误
if (readFile.bad() || readFile.fail())
{
exit(0);
}
//文件正常打开
if (readFile.is_open())
{
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
readFile >> fdata;
if (readFile.good() && fdata != 0)
{
mat.data[mat.total_num].elem_row = i;//元素行号
mat.data[mat.total_num].elem_col = j;//元素列号
mat.data[mat.total_num].elem_value = fdata;//元素之
mat.total_num++;//存储数组下标+1
}
}
}
}
readFile.close();
}
//指定位置赋值,若不存在,则插入
bool Value(int elem, int i, int j)
{
if (i >= mat.total_row || j >= mat.total_col)
{
return false;
}
else
{
int k = 0, k1;
//搜索行号<3,5> <3,6> <3,7> <3,8> 查找<3,6>
while (k<mat.total_num&&i>mat.data[k].elem_row)
{
k++;
}
//行号相等时,搜索列号
while (k<mat.total_num&&i == mat.data[k].elem_row&&j>mat.data[k].elem_col)
{
k++;
}
//退出时行号和列号相等于给定值
if (mat.data[k].elem_row == i&&mat.data[k].elem_col == j)
{
mat.data[k].elem_value = elem;
}
//退出时行号列号不都等于给定值
else
{
//三元组中位于该位置后的元素都后移
for (k1 = mat.total_num - 1; k1 >= k; k1--)
{
mat.data[k1 + 1].elem_row = mat.data[k1].elem_row;
mat.data[k1 + 1].elem_col = mat.data[k1].elem_col;
mat.data[k1 + 1].elem_value = mat.data[k1].elem_value;
}
//插入值
mat.data[k].elem_row = i;
mat.data[k].elem_col = j;
mat.data[k].elem_value = elem;
mat.total_num++;
}
}
return true;
}
//查找并输出值
bool Assign(int &res, int i, int j)
{
if (i > mat.total_row || j > mat.total_col)
{
res = 0;
return false;
}
else
{
int k = 0;
//查找行
while (k<mat.total_num&&i>mat.data[k].elem_row)
{
k++;
}
//行数匹配,查找列
while (k<mat.total_num&&i == mat.data[k].elem_row&&j>mat.data[k].elem_col)
{
k++;
}
//找到
if (i == mat.data[k].elem_row&&j == mat.data[k].elem_col)
{
res = mat.data[k].elem_value;
return true;
}
//否则
else
{
res = 0;
return false;
}
}
}
//输出三元组
void DispMat()
{
if (mat.total_num <= 0)
{
return;
}
else
{
int i;
for (i = 0; i < mat.total_num; i++)
{
cout << "<" << mat.data[i].elem_row << "," << mat.data[i].elem_col << "," << mat.data[i].elem_value << ">" << endl;
}
}
}

//输出三元组
void DispMat(Node mat)
{
if (mat.total_num <= 0)
{
return;
}
else
{
int i;
for (i = 0; i < mat.total_num; i++)
{
cout << "<" << mat.data[i].elem_row << "," << mat.data[i].elem_col << "," << mat.data[i].elem_value << ">" << endl;
}
}
}
//转置矩阵
Node TranMat()
{
Node tranMat;
tranMat.total_col = 0;
tranMat.total_row = 0;
tranMat.total_num = 0;
if (mat.total_num <= 0)
{
return tranMat;
}
else
{
int p = 0, i, c;
tranMat.total_col = mat.total_col;
tranMat.total_row = mat.total_row;
tranMat.total_num = mat.total_num;
for (i = 0; i < mat.total_row; i++)//遍历所有行
{
for (c = 0; c < mat.total_num; c++)//对于行,遍历所有三元组元素
{
if (i == mat.data[c].elem_row)//若三元组中存在行号与i相等的组,则转置
{
tranMat.data[p].elem_row = mat.data[c].elem_col;
tranMat.data[p].elem_col = mat.data[c].elem_row;
tranMat.data[p].elem_value = mat.data[c].elem_value;
p++;
}
}
}
return tranMat;
}
}
//矩阵相加

Node MatAdd(Node mat1, Node mat2)
{
Node mat;
//循环变量初始化
int i = 0, j = 0, k = 0;
//三元组初始化
mat.total_col = 0;
mat.total_num = 0;
mat.total_row = 0;
//矩阵不可相加
if (mat1.total_col != mat2.total_col || mat1.total_row != mat2.total_row)
{
return mat;
}
//课相加
else
{
//总行列数赋值
mat.total_row = mat1.total_row;
mat.total_col = mat1.total_col;
//遍历三元组
while (i < mat1.total_num&&j < mat2.total_num)
{
//两个三元组中对应元素行坐标相等
if (mat1.data[i].elem_row == mat2.data[j].elem_row)
{
//对应列坐标mat1小
if (mat1.data[i].elem_col < mat2.data[j].elem_col)
{
//赋值
mat.data[k].elem_row = mat1.data[i].elem_row;
mat.data[k].elem_col = mat1.data[k].elem_col;
mat.data[k].elem_value = mat1.data[i].elem_value;
k++;
i++;
}
//对应列坐标mat1大
else if (mat1.data[i].elem_col>mat2.data[j].elem_col)
{
//赋值
mat.data[k].elem_row = mat2.data[j].elem_row;
mat.data[k].elem_col = mat2.data[j].elem_col;
mat.data[k].elem_value = mat2.data[k].elem_value;
k++;
j++;
}
//对应列坐标也相等
else
{
//求对应元素和
int temp_value = mat1.data[i].elem_value + mat2.data[j].elem_value;
//若和值不等于0则赋值
if (temp_value != 0)
{
mat.data[k].elem_row = mat1.data[i].elem_row;
mat.data[k].elem_col = mat1.data[i].elem_col;
mat.data[k].elem_value = temp_value;
k++;
}
i++;
j++;
}
}
//对应行坐标mat1小
else if (mat1.data[i].elem_row < mat2.data[j].elem_row)
{
//赋值
mat.data[k].elem_row = mat1.data[i].elem_row;
mat.data[k].elem_col = mat1.data[i].elem_col;
mat.data[k].elem_value = mat1.data[i].elem_value;
k++;
j++;
}
//对应行坐标mat1大
else
{
//赋值
mat.data[k].elem_row = mat2.data[j].elem_row;
mat.data[k].elem_col = mat2.data[j].elem_col;
mat.data[k].elem_value = mat2.data[j].elem_value;
k++;
j++;
}
}
//总元素个数
mat.total_num = k;
return mat;
}
}
//获取矩阵首地址
Node &get_address()
{
return mat;
}
private:
Node mat;
};

//三元组操作
class operation
{
public:
operation()
{
m_mat.CreateMat("data",6,7);
}
~operation(){}
//输出
void display()
{
cout << "Output" << endl;
m_mat.DispMat();
}
//矩阵转置
void trange()
{
cout << "Change" << endl;
m_mat.DispMat(m_mat.TranMat());
}
//查找
void is_fond()
{
cout << "Fond Value" << endl;
int res;
m_mat.Assign(res, 2, 0);
cout << res << endl;
}
//赋值
void give_value()
{
cout << "Give New Value" << endl;
m_mat.Value(18, 3, 4);
m_mat.DispMat();
}
//矩阵相加
void MatAdd()
{
cout << "Matrix Add" << endl;
Matrix m_mat2;
m_mat2.CreateMat("data1", 6, 7);
m_mat.DispMat(m_mat.MatAdd(m_mat.get_address(), m_mat2.get_address()));
}
private:
Matrix m_mat;
};
int main()
{
operation m_opr;
m_opr.display();//输出
m_opr.give_value();//赋值
m_opr.is_fond();//查找
m_opr.trange();//转置
m_opr.MatAdd();
return 0;
}


测试结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: