C语言数据结构学习笔记(9)-稀疏矩阵的三元组加乘法、转置

/*
稀疏矩阵的三元组顺序表基本表示及加乘法、转置
输出结果为:
请输入第一个稀疏矩阵的行数,列数,非零元素个数:3 3 3
请输入稀疏矩阵的行数,列数,非零元素值:1 1 1
请输入稀疏矩阵的行数,列数,非零元素值:2 2 2
请输入稀疏矩阵的行数,列数,非零元素值:3 1 3
输出三元组数组:
Row     Col     Item
1       1       1
2       2       2
3       1       3
输出稀疏矩阵:
1       0       0
0       2       0
3       0       0
稀疏矩阵为3行3列,共3个非零元素.

请输入第二个稀疏矩阵的行数,列数,非零元素个数:3 3 3
请输入稀疏矩阵的行数,列数,非零元素值:1 1 2
请输入稀疏矩阵的行数,列数,非零元素值:2 1 2
请输入稀疏矩阵的行数,列数,非零元素值:3 1 2
输出三元组数组:
Row     Col     Item
1       1       2
2       1       2
3       1       2
输出稀疏矩阵:
2       0       0
2       0       0
2       0       0
稀疏矩阵为3行3列,共3个非零元素.

两个稀疏矩阵相加以后.
输出三元组数组:
Row     Col     Item
1       1       3
2       1       2
2       2       2
3       1       5
输出稀疏矩阵:
3       0       0
2       2       0
5       0       0
稀疏矩阵为3行3列,共4个非零元素.

两个稀疏矩阵相乘以后.
输出三元组数组:
Row     Col     Item
1       1       2
3       1       6
输出稀疏矩阵:
2       0       0
0       0       0
6       0       0
稀疏矩阵为3行3列,共2个非零元素.

请输入第三个稀疏矩阵的行数,列数,非零元素个数:4 3 6
请输入稀疏矩阵的行数,列数,非零元素值:1 1 2
请输入稀疏矩阵的行数,列数,非零元素值:1 2 1
请输入稀疏矩阵的行数,列数,非零元素值:2 2 6
请输入稀疏矩阵的行数,列数,非零元素值:3 1 3
请输入稀疏矩阵的行数,列数,非零元素值:3 3 5
请输入稀疏矩阵的行数,列数,非零元素值:4 2 4
输出三元组数组:
Row     Col     Item
1       1       2
1       2       1
2       2       6
3       1       3
3       3       5
4       2       4
输出稀疏矩阵:
2       1       0
0       6       0
3       0       5
0       4       0
稀疏矩阵为4行3列,共6个非零元素.

第三个稀疏矩阵转置后
输出三元组数组:
Row     Col     Item
1       1       2
1       3       3
2       1       1
2       2       6
2       4       4
3       3       5
输出稀疏矩阵:
2       0       3       0
1       6       0       4
0       0       5       0
稀疏矩阵为3行4列,共6个非零元素.

请按任意键继续. . .
*/
# include
# include
# define MAX 100
# define OK 1
# define ERROR 0
typedef int Status;
typedef struct
{
    int row, col;//三元组的行号,列号
    int item;//三元组的元素值
}Triple;
typedef struct
{
    Triple data[MAX];//非零元素数组
    int mu, nu, num;//稀疏矩阵的行数,列数,非零元素个数
}TSMatrix;

void InitTSMatrix(TSMatrix * pTSM, int m , int n);//初始化稀疏矩阵
void InputTSMatrix(TSMatrix * pTSM, int m , int n, int num);//输入三元组元素
Status SetItem(TSMatrix * pTSM, int row, int col, int item);//添加三元组元素
int GetItem(TSMatrix TSM, int row, int col);//根据行,列获取矩阵元素值
void ShowTriple(TSMatrix TSM);//输出三元组数组
void ShowTSMatrix(TSMatrix TSM);//输出稀疏矩阵
Status AddTSMatrix(TSMatrix A, TSMatrix B, TSMatrix * C);//稀疏矩阵的加法
Status MultiplyTSMatrix(TSMatrix A, TSMatrix B, TSMatrix * D);//稀疏矩阵的乘法
void TransposeTSMatrix(TSMatrix M, TSMatrix * T);//稀疏矩阵的转置

int main(void)
{    
    int m , n, num;
    printf("请输入第一个稀疏矩阵的行数,列数,非零元素个数:");
    scanf("%d %d %d", &m, &n, &num);
    TSMatrix A;
    InitTSMatrix(&A, m, n);
    InputTSMatrix(&A, m , n, num);
    ShowTriple(A);
    ShowTSMatrix(A);

    printf("请输入第二个稀疏矩阵的行数,列数,非零元素个数:");
    scanf("%d %d %d", &m, &n, &num);
    TSMatrix B;
    InitTSMatrix(&B, m, n);
    InputTSMatrix(&B, m , n, num);
    ShowTriple(B);
    ShowTSMatrix(B);

    TSMatrix C;
    InitTSMatrix(&C, m, n);
    printf("两个稀疏矩阵相加以后.\n");
    if(AddTSMatrix(A, B, &C))
    {    
        ShowTriple(C);
        ShowTSMatrix(C);
    }
    else
    {
        printf("两个稀疏矩阵的行数或列数不相同,无法相加.\n");
    }

    TSMatrix D;
    InitTSMatrix(&D, m, n);
    printf("两个稀疏矩阵相乘以后.\n");
    if(MultiplyTSMatrix(A, B, &D))
    {
        ShowTriple(D);
        ShowTSMatrix(D);
    }
    else
    {
        printf("两个稀疏矩阵的行数或列数不相同,无法相乘.\n");
    }

    printf("请输入第三个稀疏矩阵的行数,列数,非零元素个数:");
    scanf("%d %d %d", &m, &n, &num);
    TSMatrix M;
    InitTSMatrix(&M, m, n);
    InputTSMatrix(&M, m , n, num);
    ShowTriple(M);
    ShowTSMatrix(M);
    TSMatrix T;
    TransposeTSMatrix(M, &T);
    printf("第三个稀疏矩阵转置后\n");
    ShowTriple(T);
    ShowTSMatrix(T);

    system("pause");
    return 0;
}
void InitTSMatrix(TSMatrix * pTSM, int m , int n)//初始化稀疏矩阵
{
    pTSM->mu = m;
    pTSM->nu = n;
    pTSM->num = 0;
}
void InputTSMatrix(TSMatrix * pTSM, int m , int n, int num)//输入三元组元素
{
    int row, col, item;
    for(int i = 1; i <= num; i++)
    {    
        printf("请输入稀疏矩阵的行数,列数,非零元素值:");
        scanf("%d %d %d", &row, &col, &item);
        if(item != 0)
        {
            if(ERROR == SetItem(pTSM, row, col, item))
            {
                printf("稀疏矩阵的行数或列数错误或三元组已满.\n");
                break;
            }
        }
    }
}
Status SetItem(TSMatrix * pTSM, int row, int col, int item)//添加三元组元素
{
    if(row > pTSM->mu || col > pTSM->nu)
        return ERROR;
    if(MAX == pTSM->num)
        return ERROR;
    if(0 == item)
        return OK;
    int index = 0;
    while(index < pTSM->num)
    {
        if(row > pTSM->data[index].row)
            index++;
        else if(row == pTSM->data[index].row && col > pTSM->data[index].col)
            index++;
        else
            break;
    }
    if(row == pTSM->data[index].row && col == pTSM->data[index].col)
        pTSM->data[index].item = item;
    else
    {
        for(int i = pTSM->num; i > index; i--)
        {
            pTSM->data[i] = pTSM->data[i-1];
        }
        pTSM->data[index].row = row;
        pTSM->data[index].col = col;
        pTSM->data[index].item = item;
        pTSM->num++;
    }
    return OK;
}
int GetItem(TSMatrix TSM, int row, int col)//根据行,列获取矩阵元素值
{
    if(row > TSM.mu || col > TSM.nu)
        return 0;
    for(int i = 0; i < TSM.num; i++)
    {
        if(row == TSM.data[i].row && col == TSM.data[i].col)
            return TSM.data[i].item;
    }
    return 0;
}
void ShowTriple(TSMatrix TSM)//输出三元组数组
{
    printf("输出三元组数组:\n");
    printf("Row\tCol\tItem\n");
    for(int i = 0; i < TSM.num; i++)
        printf("%d\t%d\t%d\n", TSM.data[i].row, TSM.data[i].col, TSM.data[i].item);
}
void ShowTSMatrix(TSMatrix TSM)//输出稀疏矩阵
{
    int index = 0;
    printf("输出稀疏矩阵:\n");
    for(int i = 1; i <= TSM.mu; i++)
    {    
        for(int j = 1; j <= TSM.nu; j++)
        {    
            if(i == TSM.data[index].row && j == TSM.data[index].col)
            {
                printf("%d\t", TSM.data[index].item);
                index++;
            }
            else
                printf("0\t");
        }
        printf("\n");
    }
    printf("稀疏矩阵为%d行%d列,共%d个非零元素.\n\n", TSM.mu, TSM.nu, TSM.num);
}

Status AddTSMatrix(TSMatrix A, TSMatrix B, TSMatrix * C)//稀疏矩阵的加法
{
    if(A.mu != B.mu || B.mu != C->mu || A.nu != B.nu || B.nu != C->nu)
        return ERROR;
    else
    {    
        for(int i = 1; i <= A.mu; i++)
        {
            for(int j = 1; j <= A.nu; j++)
            {
                int result = GetItem(A, i, j) + GetItem(B, i, j);
                if(result != 0)
                    SetItem(C, i, j, result );
            }
        }
        return OK;
    }
}

Status MultiplyTSMatrix(TSMatrix A, TSMatrix B, TSMatrix * D)//稀疏矩阵的乘法
{
    if(A.nu != B.mu)
        return ERROR;
    else
    {    
        D->mu = A.mu;
        D->nu = B.nu;
        for(int i = 1; i <= A.mu; i++)
        {
            for(int j = 1; j <= B.nu; j++)
            {    
                int sum = 0;
                for(int k = 1; k <= A.nu; k++)
                {
                    sum += GetItem(A, i, k) * GetItem(B, k, j);
                }
                if(sum != 0)
                {
                    SetItem(D, i, j, sum);
                }
            }
        }
        return OK;
    }
}

void TransposeTSMatrix(TSMatrix M, TSMatrix * T)//稀疏矩阵的转置
{    
    //快速转置
    T->mu = M.nu;
    T->nu = M.mu;
    T->num = M.num;
    if(T->num)
    {    
        int * cNum = (int*)malloc(sizeof(int)*M.nu);
        if(NULL == cNum)
            exit(-1);
        for(int col = 0; col < M.nu; col++)
            cNum[col] = 0;
        for(int i = 0; i < M.num; i++)
            cNum[M.data[i].col]++;

        int * cPos = (int*)malloc(sizeof(int)*M.num);
        if(NULL == cPos)
            exit(-1);
        cPos[0] = 0;
        for(int col = 1; col < M.num; col++)
            cPos[col] = cPos[col-1] + cNum[col-1];
        for(int p = 0; p <  M.num; p++)
        {    
            int index = cPos[M.data[p].col];
            T->data[index].row = M.data[p].col;
            T->data[index].col = M.data[p].row;
            T->data[index].item = M.data[p].item;
            cPos[M.data[p].col]++;
        }
    }
    /*
    //普通转置
    T->mu = M.nu;
    T->nu = M.mu;
    T->num = M.num;
    if(T->num)
    {
        int index = 0;
        for(int col = 1; col <= M.nu; col++)
        {
            for(int p = 0; p < M.num; p++)
            {
                if(col == M.data[p].col)
                {
                    T->data[index].row = M.data[p].col;
                    T->data[index].col = M.data[p].row;
                    T->data[index].item = M.data[p].item;
                    index++;
                }
            }
        }
    }
    */
}

你可能感兴趣的:(数据结构,c语言,矩阵)