##在进行链表储存的稀疏矩阵类相关操作
#报多个类似错误
error C2440: “初始化”: 无法从“node *”转换为“node<hnode> *”
1> with
1> [
1> T=cnode
1> ]
1> and
1> [
1> T=int
1> ]
1>homework3.3.cpp(171,24): message : 指向的类型不相关; 转换需要 reinterpret_cast、C 样式强制转换或带圆括号的函数样式强制转换
1>homework3.3.cpp(168,61): message : 在编译 类 模板 成员函数“linkedmatrix &linkedmatrix::plus(linkedmatrix &)”时
1>homework3.3.cpp(469,30): message : 请参阅 "main" 中对 "linkedmatrix::plus" 的第一个引用
1>homework3.3.cpp(459,20): message : 查看对正在编译的 类 模板 实例化“linkedmatrix”的引用
#给出全部代码,为什么会报错呢?
#include<iostream>
using namespace std;
template<class T>
class node {
public:
T data;
node<T>* next;
node<T>() { data = 0; next = nullptr; }
node<T>(T a) { data = a; next = nullptr; }
};
template<class T>
class chain {
public:
int length;
node<T>* first;
node<T>* tail;
bool isempty() { return (first == nullptr); }
chain<T>() { length = 0; first = tail = nullptr; }
void insert(T a);
};
template<class T>
void chain<T>::insert(T a) {
node<T>* p = new node<T>(a);
if (isempty()) {
first = p;
tail = p;
length++;
}
else {
tail->next = p;
tail = p;
length++;
}
}
template<class T>
class cnode {
public:
int col;
T value;
int operator !=(cnode<T> a) { return (value != a.value); }
};
template<class T>
ostream& operator<<(ostream& out, cnode<T>& a) {
out << "col=" << a.col << " " << "value=" << a.value << endl;
return out;
}
template<class T>
istream& operator>>(istream& in, cnode<T>& a) {
cout << "please input column" << endl;
in >> a.col;
cout << "please input value" << endl;
in >> a.value;
return in;
}
template<class T>
class hnode {
public:
int row;
chain<cnode<T>> b;
int operator !=(hnode<T>& a) { return (row != a.row); }
};
template<class T>
ostream& operator<<(ostream& out, hnode<T>& a) {
out << "row=" << a.row << endl;
return out;
}
template<class T>
istream& operator>>(istream& in, hnode<T>& a) {
cout << "please input row" << endl;
in >> a.row;
return in;
}
template<class T>
class linkedmatrix {
public:
int rows;
int cols;
int num;
chain<cnode<T>> a;
template<class T>
friend ostream& operator<<(ostream& out, linkedmatrix<T>& x);
template<class T>
friend istream& operator>>(istream& in, linkedmatrix<T>& x);
linkedmatrix<T> &plus(linkedmatrix<T>& x); //加
linkedmatrix<T> &sub(linkedmatrix<T>& x); //减
linkedmatrix<T> &mul(linkedmatrix<T>& x); //乘
void transpose(linkedmatrix<T>& x);
void set(int i, int j, T x); //存入
T get(int i, int j); //取出
linkedmatrix(int r, int c) {
rows = r;
cols = c;
}
linkedmatrix() {
rows = 0;
cols = 0;
num = 0;
}
};
template<class T>
ostream& operator<<(ostream& out, linkedmatrix<T>& x) {
out << "rows=" << x.rows << " cols=" << x.cols << endl;
node<hnode<T>> *p = x.a.first;//每一行的头节点组成的链表的首节点
while (p) {
hnode<T> temp = p->data;
if (temp.b.first) {//每一行
node<cnode<T>>* q = temp.b.first;
cout << temp;
while (q) {
cnode<T> temp2 = q->data;
cout << temp2;
q = q->next;
}
cout << endl;
}
p = p->next;
}
return out;
}
template<class T>
istream& operator>>(istream& in, linkedmatrix<T>& x) {
cout << "please input rows and columns" << endl;
in >> x.rows >> x.cols;
cout << "please input the numbers" << endl;
in >> x.num;
int i, j;
T a;
for (int k = 0; k < x.num; k++) {
cout << "input the row, column and value of" << k << endl;
cin >> i >> j >> a;
x.set(i, j, a);
}
}
template<class T>//转置矩阵
void linkedmatrix<T>::transpose(linkedmatrix<T>& x) {
node<hnode<T>>* temp1 = a.first;
node<cnode<T>>* temp2 = temp1->data.b.first;
while (temp1) //遍历所有行
{
node<cnode<T>>* link = temp2;
while (link) //遍历所有列
{
x.set(link->data.value, link->data.col, temp1->data.row); //转置后位置放入
next = next->link; //当前行下一个元素
}
temp1 = temp1->next;
if (!temp1)
break;
temp2 = temp1->data.b.first;
}
}
//加法
template<class T>
linkedmatrix<T> & linkedmatrix<T>::plus(linkedmatrix<T>& x) {
linkedmatrix<T> m(rows, cols);
node<hnode<T>> *temp1 = a.first;//指向矩阵的行头节点组成的链表的第一个节点
node<hnode<T>> *temp2 = x.a.first;
node<hnode<T>> *temp3 = m.a.first;
while (temp1 && temp2) { //同时遍历两个链表的每一行
node<cnode<T>> *temp4 = temp1->data.b.first; //指向每一行的非零元素组成的链表的第一个
node<cnode<T>> *temp5 = temp2->data.b.first;
//当两个行链表都不为空时
while (temp4 && temp5) {
//列号相等则进行加法
if (temp4->data.col == temp5->data.col) {
if (temp4->data.value + temp5->data.value) { //如果相加后的value不为0则插入到新行链表中
cnode<T> a;
a.col = temp4->data.col;
a.value = temp4.data.value + temp5->data.value;
temp3->data.b.insert(a);//插入到结果矩阵的相应行中
}
temp4 = temp4->next;
temp5 = temp5->next;
if (!(temp4 && temp5)) {//如果为空 该行遍历完成
break;
}
}
//一个的列号小于另一个列号,则将前一个插进新链表,并将前一个行链表指针右移
if (temp4->data.col < temp5->data.col) {
cnode<T> a;
a.col = temp4->data.col;//列号和值为*this矩阵对应非零元素的列号和值
a.value = temp4->data.value;
temp3->data.b.insert(a);//插入到结果矩阵中
temp4 = temp4->next;
if (!temp4) {
break;
}
}
//一个的列号大于另一个列号,则将后一个插进新链表,并将后一个行链表指针右移
if (temp4->data.col > temp5->data.col) {
cnode<T> a;
a.col = temp5->data.col;//列号和值为x矩阵对应非零元素的列号和值
a.value = temp5->data.value;
temp3->data.b.insert(a);//插入到结果矩阵中
temp5 = temp5->next;
if (!temp5) {
break;
}
}
}
//后一个行链表已经遍历完,则把前一个链表所有剩余元素插进新链表
while (temp4 && !temp5) {
cnode<T> a;
a.col = temp4->data.col;
a.value = temp4->data.value;
temp3->data.b.insert(a);
temp4 = temp4->next;
}
//前一个行链表已经遍历完,则把后一个链表所有剩余元素插进新链表
while (!temp4 && temp5) {
cnode<T> a;
a.col = temp5->data.col;
a.value = temp5->data.value;
temp3->data.b.insert(a);
temp5 = temp5->next;
}
temp1 = temp1->next;//指向下一行
temp2 = temp2->next;
temp3 = temp3->next;
}
return m;
}
//相减
template<class T>
linkedmatrix<T> & linkedmatrix<T>::sub(linkedmatrix<T>& x) {
linkedmatrix<T> m(rows, cols);
node<hnode<T>>* temp1 = a.first;//指向矩阵的行头节点组成的链表的第一个节点
node<hnode<T>>* temp2 = x.a.first;
node<hnode<T>>* temp3 = m.a.first;
//同时遍历两个链表的每一行
while (temp1 && temp2) {
node<cnode<T>>* temp4 = temp1->data.b.first;//指向每一行的非零元素组成的链表的第一个
node<cnode<T>>* temp5 = temp2->data.b.first;
//当两个行链表都不为空时
while (temp4 && temp5) {
if (temp4->data.col == temp5->data.col) {//列号相等则进行减法
if (temp4->data.value - temp5->data.value) {//如果相减后的value不为0则插入到新行链表中
cnode<T> a;
a.col = temp4->data.col;
a.value = temp4.data.value - temp5->data.value;
temp3->data.b.insert(a);
}
temp4 = temp4->next;
temp5 = temp5->next;
if (!(temp4 && temp5)) {
break;
}
}
//一个的列号小于另一个列号,则将前一个插进新链表,并将前一个行链表指针右移
if (temp4->data.col < temp5->data.col) {
cnode<T> a;
a.col = temp4->data.col;
a.value = temp4->data.value;
temp3->data.b.insert(a);
temp4 = temp4->next;
if (!temp4) {
break;
}
}
//一个的列号大于另一个列号,则将后一个插进新链表,并将后一个行链表指针右移
if (temp4->data.col > temp5->data.col) {
cnode<T> a;
a.col = temp5->data.col;
a.value = -(temp5->data.value);
temp3->data.b.insert(a);
temp5 = temp5->next;
if (!temp5) {
break;
}
}
}
//后一个行链表已经遍历完,则把前一个链表所有剩余元素插进新链表
while (temp4 && !temp5) {
cnode<T> a;
a.col = temp4->data.col;
a.value = temp4->data.value;
temp3->data.b.insert(a);
temp4 = temp4->next;
}
//前一个行链表已经遍历完,则把后一个链表所有剩余元素插进新链表
while (!temp4 && temp5) {
cnode<T> a;
a.col = temp5->data.col;
a.value = -(temp5->data.value);
temp3->data.b.insert(a);
temp5 = temp5->next;
}
temp1 = temp1->next;//指向下一行
temp2 = temp2->next;
temp3 = temp3->next;
}
return m;
}
//乘法
template<class T>
linkedmatrix<T>& linkedmatrix<T>::mul(linkedmatrix<T>& x) {
linkedmatrix<T> y(x.cols, x.rows); //转置后矩阵
linkedmatrix<T> z(rows, x.cols); //结果矩阵
x.transpose(y);//转置后,乘法简化为两个双层链表逐行相乘
node<hnode<T>>* temp1 = a.first;//指向矩阵的行头节点组成的链表的第一个
node<hnode<T>>* temp2 = y.a.first;
node<cnode<T>>* z1 = temp1->data.b.first;//指向矩阵每一行的非零元素组成的链表的第一个
node<cnode<T>>* z2 = temp2->data.b.first;
T sum = 0;//sum用来记录两行相乘后的数值
while (temp1)//依次遍历*this矩阵的每一行
{
if (z1)//如果行链表不为空
{
while (temp2)//依次遍历y矩阵的每一行
{
//第二个矩阵的行链表为空,移动到其下一行
while (!z2)
{
temp2 = temp2->next;
if (!temp2) { //temp2为空说明矩阵x中已经没有非零元素 结束循环
return z;
}
z2 = temp2->data.b.first;
}
//两个行链表都不为空则判断列号
while (z1 && z2)
{
//如果z1的列号大于z2的列号 z2右移
while (z1->data.col > z2->data.col)
{
z2 = z2->next;
if (!z2)//如果z2为空
goto L;//进入下一行
}
//如果z2的列号大于z1的列号 z1右移
while (z1->data.col < z2->data.col)
{
z1 = z1->next;
if (!z1)//如果z1为空
goto L;//指向下一行
}
//如果相等则相乘
if (z1->data.col == z2->data.col)
{
sum += z1->data.value * z2->data.value;
z1 = z1->next;
z2 = z2->next;
}
L:;
}
if (sum)//当sum不为0则插进新链表
{
z.set(sum, temp1->data.row, temp2->data.row);
sum = 0;//sum重置
}
z1 = temp1->data.b.first; //z1重新指向*this当前行起始位置
temp2 = temp2->next;//指向下一行
if (!temp2)//temp2为空说明矩阵y中没有非零元素
break;
z2 = temp2->data.b.first;
}
}
temp1 = temp1->next; //*this下一行
if (!temp1)//temp1为空说明*this矩阵中没有非零元素
break;
z1 = temp1->data.b.first;
temp2 = y.a.first;//重新指向第一个行头节点
z2 = temp2->data.b.first;
}
return z;
}
template<class T>
void linkedmatrix<T>::set(int i, int j, T x) {
node<hnode<T>> *p = a.first;
while (p->data.row != i) {//p移动到所在行
p = p->next;
}
node<cnode<T>>* q = p->data.b.first;//指向第r行行列表的头节点
//如果此行为空 直接插入
if (!q) {
q = new node<cnode<T>>;
q->data.col = j;
q->data.value = x;
p->data.b.insert(q->data.value);
return *this;
}
int num = 0;//表示插入到链表中的具体位置坐标
//如果此行不为空 遍历插入相应位置
while (q) {
if (q->data.col > j) {//当前col比列号大 插入到num位置(前面一位)
node<cnode<T>> *temp = new node<cnode<T>>;
temp->data.col = j;
temp->data.value = x;
p->data.b.insert(temp->data.value);
return *this;
}
if (q->data.col == j) {
cout << "此位置已存在数据,无法存入" << endl;
return *this;
}
q = q.next;
num++;
}
node<cnode<T>> *q1 = new node<cnode<T>>;//如果没有合适位置 插入队尾
q1->data.col = j;
q1->data.value = x;
p->data.b.insert(q1->data.value);
return *this;
}
template<class T>
T linkedmatrix<T>::get(int i, int j) {
node<hnode<T>> *p = a.first;
hnode<T> temp = p->data;
//找到正确行
while (temp.row != i) {
p = p->next;
temp = p->data;
}
node<cnode<T>> *q = temp.b.first;
cnode<T> temp1 = q->data;
while (temp1.col < j && q) {
q = q->next;
temp1 = q->next;
}
return temp1.value;
}
int main() {
linkedmatrix<int> a, b;
cin >> a;
cin >> b;
int i, j, v;
cout << "pleasr input the row,column and value of the element that you want to store" << endl;
cin >> i >> j >> v;
a.set(i, j, v);
cout << "please input the row and column of the element that you want to get" << endl;
cin >> i >> j;
a.get(i, j);
cout << "a+b=" << a.plus(b) << endl;
cout << "a-b=" << a.sub(b) << endl;
cout << "a*b=" << a.mul(b) << endl;
return 0;
}