稀疏矩阵的乘法

使用十字链表可以大大简化计算,就完完全全的模拟手算,不再赘述

// 稀疏矩阵的乘法
#include <iostream>
using namespace std;
struct Node
{
    int row;
    int col;
    int value;
    Node *right;
    Node *down;
};

struct CrossList
{
    Node *rows[100] = {0};
    Node *cols[100] = {0};
    int rowNum;
    int colNum;
    int elements;

public:
    void insertAElement(int row, int col, int value);
    void createCorssList(int rowsNum, int colsNum);
};

void multiTwoMartix(CrossList *martixA, CrossList *martixB, CrossList *martixC)
{
    martixC->rowNum = martixC->colNum = 0;
    for (int i = 1; i <= martixA->rowNum; i++)
    {
        int nowEle = 0;
        for (int j = 1; j <= martixB->colNum; j++)
        {
            Node *A = martixA->rows[i], *B = martixB->cols[j];
            while (A && B)
            {
                if (A->col == B->row)
                {
                    nowEle += A->value * B->value;
                    A = A->right;
                    B = B->down;
                }
                else if (A->col < B->row)
                {
                    A = A->right;
                }
                else
                {
                    B = B->down;
                }
            }
            if (nowEle != 0)
            {
                martixC->insertAElement(i, j, nowEle);
                nowEle = 0;
            }
        }
        if (martixC->rows[i] != nullptr)
        {
            martixC->rowNum++;
        }
        
    }
}
void CrossList::insertAElement(int row, int col, int value)
{
    Node *newNode = new Node;
    newNode->row = row;
    newNode->col = col;
    newNode->value = value;
    newNode->right = newNode->down = nullptr;
    //处理行
    if (!rows[row])
    {
        rows[row] = newNode;
    }
    else if (col < rows[row]->col)
    {
        newNode->right = rows[row];
        rows[row] = newNode;
    }
    else
    {
        Node *temp;
        for (temp = rows[row]; temp->right && temp->right->col < col; temp = temp->right)
            ;
        newNode->right = temp->right;
        temp->right = newNode;
    }

    //处理列
    if (!cols[col])
    {
        cols[col] = newNode;
    }
    else if (row < cols[col]->row)
    {
        newNode->down = cols[col];
        cols[col] = newNode;
    }
    else
    {
        Node *temp;
        for (temp = cols[col]; temp->down && temp->down->row < row; temp = temp->down)
            ;
        newNode->down = temp->down;
        temp->down = newNode;
    }
}

void CrossList::createCorssList(int rowsNum, int colsNum)
{
    this->rowNum = rowsNum;
    this->colNum = colsNum;
    this->elements = 0;
    int row, col, val;

    while (1)
    {
        cin >> row >> col >> val;
        if (row == 0)
        {
            break;
        }
        else
        {
            this->elements++;
            this->insertAElement(row, col, val);
        }
    }
}

int main()
{
    CrossList *martixA = new CrossList;
    CrossList *martixB = new CrossList;
    CrossList *martixC = new CrossList;
    int rowsA = 0, colsA = 0;
    int rowsB = 0, colsB = 0;
    int rowsC = 0, colsC = 0;
    cin >> rowsA >> colsA;
    martixA->createCorssList(rowsA, colsA);
    cin >> rowsB >> colsB;
    martixB->createCorssList(rowsB, colsB);
    multiTwoMartix(martixA, martixB, martixC);
    for (int i = 1; i <= martixC->rowNum; i++)
    {
        Node* temp = martixC->rows[i];
        while (temp)
        {
            cout << temp->row << " " << temp->col << " " << temp->value << endl;
            temp = temp->right;
        }
    }
}

  

posted @ 2022-04-05 18:39  帝皇の惊  阅读(72)  评论(0)    收藏  举报