数据结构之矩阵


矩阵乘

这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明

一、矩阵乘的计算

矩阵乘这里定义了两个结构体,一个采用动态分配空间,数组长度不定,一个采用静态分配空间。

1.结构体的定义:

/*动态分配大小*/
typedef struct TwoDArray
{
    int row;
    int col;
    int** element;
}TwoDArray,*TwoDArrayPtr;

/*数组大小固定*/
typedef struct TwoDStaticArray{
	int row;
	int col;
	int element[ROW][COL];
} TwoDStaticArray, *TwoDStaticArrayPtr;

2.初始化

主要是动态分配内存空间。

/* 初始化 */
TwoDArrayPtr initTwoDArray(int paraRow,int paraCol)
{
    int i;
    TwoDArrayPtr resultPtr=(TwoDArrayPtr)malloc(sizeof(struct TwoDArray));
    resultPtr->row=paraRow;
    resultPtr->col=paraCol;
    resultPtr->element=(int**)malloc(paraRow*sizeof(int*));

    for(i=0;i<paraRow;i++)
    {
        resultPtr->element[i]=(int*)malloc(paraCol*sizeof(int));
    }
    return resultPtr;
}

3.数组初始化

通过生成随机数的方式将数组中存入数据。

void randomizeTwoDArray(TwoDArrayPtr paraPtr,int paraLowerBound,int paraUpperBound)
{
    int i,j;
    for(i=0;i<paraPtr->row;i++)
    {
        for(j=0;j<paraPtr->col;j++)
        {
            paraPtr->element[i][j]=rand()%(paraUpperBound-paraLowerBound)+paraLowerBound;
        }
    }
}

4.数组中数据打印

void printTwoDArray(TwoDArrayPtr paraPtr)
{
    int i,j;
    for(i=0;i<paraPtr->row;i++)
    {
        for(j=0;j<paraPtr->col;j++)
        {
            printf("%d, ",paraPtr->element[i][j]);
        }
        printf("\r\n");
    }
}

5.核心矩阵乘计算。

先要判断矩阵是否能相乘的问题。

TwoDArrayPtr matrixMultiply(TwoDArrayPtr paraPtr1,TwoDArrayPtr paraPtr2)
{
    int i,j,k,sum;
    if(paraPtr1->col!=paraPtr2->row)
    {
        printf("Matrices cannot be multiplied.\r\n");
        return NULL;
    }

    TwoDArrayPtr resultPtr=initTwoDArray(paraPtr1->row,paraPtr2->col);

    for(i=0;i<paraPtr1->row;i++)
    {
        for(j=0;j<paraPtr2->col;j++)
        {
            sum=0;
            for(k=0;k<paraPtr1->col;k++)
            {
                sum+=paraPtr1->element[i][k]*paraPtr2->element[k][j];
            }
            resultPtr->element[i][j]=sum;
            printf("sum=%d, ",sum);
        }
    }
    return resultPtr;
}

6.测试函数

void twoDArrayTest()
{
    TwoDArrayPtr tempPtr1,tempPtr2,tempPtr3;
    tempPtr1=initTwoDArray(3,2);
    randomizeTwoDArray(tempPtr1,1,5);
    printf("The first matrix:\r\n");
    printTwoDArray(tempPtr1);

    tempPtr2=initTwoDArray(2,4);
    randomizeTwoDArray(tempPtr2,4,9);
    printf("The second matrix:\r\n");
    printTwoDArray(tempPtr2);

    tempPtr3=matrixMultiply(tempPtr1,tempPtr2);
    printf("The result is:\r\n");
    printTwoDArray(tempPtr3);
}

TwoDStaticArrayPtr initTwoDStaticArray()
{
    int i,j;
    TwoDStaticArrayPtr resultPtr=(TwoDStaticArrayPtr)malloc(sizeof(struct TwoDStaticArray));
    resultPtr->row=ROW;
    resultPtr->col=COL;
    for(i=0;i<ROW;i++)
    {
        for(j=0;j<COL;j++)
        {
            resultPtr->element[i][j]=i*10+j;
            printf("(%d,%d):%d;\r\n",i,j,&(resultPtr->element[i][j]));
        }
    }
    return resultPtr;
}

7.具体代码实现

#include<stdio.h>
#include<stdlib.h>

#define TOTAL_SPACE 5

typedef struct CircleIntQueue
{
	int data[TOTAL_SPACE];
	int head;
	int tail;
}*CircleIntQueuePtr;

CircleIntQueuePtr initQueue()
{
	CircleIntQueuePtr resultPtr=(CircleIntQueuePtr)malloc(sizeof(struct CircleIntQueue));
	resultPtr->head=0;
	resultPtr->tail=0;

	return resultPtr;
}

void enqueue(CircleIntQueuePtr paraPtr,int paraValue)
{
	if((paraPtr->tail+1)%TOTAL_SPACE==paraPtr->head)
	{
		printf("Queue full.\r\n");
		return ;
	}
	paraPtr->data[paraPtr->tail%TOTAL_SPACE]=paraValue;
	paraPtr->tail++;
}

int dequeue(CircleIntQueuePtr paraPtr)
{
	int resultValue;
	if(paraPtr->head==paraPtr->tail)
	{
		printf("No element in the queue.\r\n");
		return -1;
	}

	resultValue=paraPtr->data[paraPtr->head%TOTAL_SPACE];
	paraPtr->head++;

	return resultValue;
}

int queuelength(CircleIntQueuePtr paraPtr)
{
	int length=0;
	for(int i=paraPtr->head;i<paraPtr->tail;i++)
	{
		length++;
	}
	return length;
}
/**
 * Output the queue.
 */
void outputLinkQueue(CircleIntQueuePtr paraPtr)
{
	int i;
	if(paraPtr->head==paraPtr->tail)
	{
		printf("Empty queue.");
		return ;
	}
	printf("Element in the queue:");
	for(i=paraPtr->head;i<paraPtr->tail;i++)
	{
		printf("%d ",paraPtr->data[i%TOTAL_SPACE]);
	}
	printf("\r\n");
}

void testLinkQueue()
{
	printf("---Begin!---\r\n");
	int i=10;
	CircleIntQueuePtr tempPtr =initQueue();
	for(i;i<16;i++)
	{
		enqueue(tempPtr,i);
	}
	outputLinkQueue(tempPtr);
	printf("Length of the queue is %d\r\n",queuelength(tempPtr));

	for(i=0;i<6;i++)
	{
		printf("dequeue gets %d\r\n",dequeue(tempPtr));
	}
	enqueue(tempPtr,8);
	outputLinkQueue(tempPtr);
	printf("---End!---\r\n");
}
int main()
{
	testLinkQueue();
	return 0;
}

8、样例输出

The first matrix:
2, 4,
3, 1,
2, 1,
The second matrix:
7, 7, 6, 8,
4, 4, 5, 6,
sum=30, sum=30, sum=32, sum=40, sum=25, sum=25, sum=23, sum=30, sum=18, sum=18, sum=17, sum=22, The result is:
30, 30, 32, 40,
25, 25, 23, 30,
18, 18, 17, 22,
(0,0):11235192;
(0,1):11235196;
(0,2):11235200;
(0,3):11235204;
(0,4):11235208;
(1,0):11235212;
(1,1):11235216;
(1,2):11235220;
(1,3):11235224;
(1,4):11235228;
(2,0):11235232;
(2,1):11235236;
(2,2):11235240;
(2,3):11235244;
(2,4):11235248;
(3,0):11235252;
(3,1):11235256;
(3,2):11235260;
(3,3):11235264;
(3,4):11235268;

二、压缩矩阵的转置

1.矩阵压缩的定义

矩阵的压缩实际上就是将一个矩阵写成一个列数为3,行数为有效数个数的矩阵。
压缩矩阵

2.结构体的定义

typedef struct Triple
{
    int i;
    int j;
    elem e;
}Triple,*TriplePtr;

typedef struct CompressedMatrix
{
    int row;//行数
    int col;//列数
    int num;//有效数据个数
    Triple* element;//压缩矩阵
}CompressedMatrix,*CompressedMatrixPtr;

3.初始化

CompressedMatrixPtr initCompressedMatrix(int paraRow,int paraCol,int paraElement,int** paraData)
{
    int i;
    CompressedMatrixPtr resultPtr=(CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
    resultPtr->row=paraRow;
    resultPtr->col=paraCol;
    resultPtr->num=paraElement;
    resultPtr->element=(TriplePtr)malloc(paraElement*sizeof(struct Triple));

    for(i=0;i<paraElement;i++)
    {
        resultPtr->element[i].i=paraData[i][0];
        resultPtr->element[i].j=paraData[i][1];
        resultPtr->element[i].e=paraData[i][2];
    }
    return resultPtr;
}

4.矩阵的打印

void printCompressedMatrix(CompressedMatrixPtr paraPtr)
{
    for(int i=0;i<paraPtr->num;i++)
    {
        printf("(%d,%d):%d\r\n",paraPtr->element[i].i,paraPtr->element[i].j,paraPtr->element[i].e);
    }
}

5.压缩矩阵的转置

CompressedMatrixPtr transposeCompressedMatrix(CompressedMatrixPtr paraPtr)
{
    int i,tempCol,tempPosition;
    int* tempColCounts=(int*)malloc(paraPtr->col*sizeof(int));
    int* tempOffSet=(int*)malloc(paraPtr->col*sizeof(int));

    for(i=0;i<paraPtr->col;i++)
    {
        tempColCounts[i]=0;
    }

    CompressedMatrixPtr resultPtr=(CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
    resultPtr->row=paraPtr->col;
    resultPtr->col=paraPtr->row;
    resultPtr->num=paraPtr->num;

    resultPtr->element=(TriplePtr)malloc(paraPtr->num*sizeof(struct Triple));

    for(i=0;i<paraPtr->num;i++)
    {
        tempColCounts[paraPtr->element[i].j] ++;
    }
    tempOffSet[0]=0;
    for(i=1;i<paraPtr->col;i++)
    {
        tempOffSet[i]=tempOffSet[i-1]+tempColCounts[i-1];
        printf("tempOffSet[%d]=%d\r\n",i,tempOffSet[i]);
    }
    for(i=0;i<paraPtr->num;i++)
    {
        tempCol=paraPtr->element[i].j;
        tempPosition=tempOffSet[tempCol];
        resultPtr->element[tempPosition].i=paraPtr->element[i].j;
        resultPtr->element[tempPosition].j=paraPtr->element[i].i;
        resultPtr->element[tempPosition].e=paraPtr->element[i].e;

        tempOffSet[tempCol]++;
    }
    return resultPtr;
}

6.具体代码实现

#include<stdio.h>
#include<stdlib.h>

typedef int elem;

typedef struct Triple
{
    int i;
    int j;
    elem e;
}Triple,*TriplePtr;

typedef struct CompressedMatrix
{
    int row;//行数
    int col;//列数
    int num;//有效数据个数
    Triple* element;//压缩矩阵
}CompressedMatrix,*CompressedMatrixPtr;

CompressedMatrixPtr initCompressedMatrix(int paraRow,int paraCol,int paraElement,int** paraData)
{
    int i;
    CompressedMatrixPtr resultPtr=(CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
    resultPtr->row=paraRow;
    resultPtr->col=paraCol;
    resultPtr->num=paraElement;
    resultPtr->element=(TriplePtr)malloc(paraElement*sizeof(struct Triple));

    for(i=0;i<paraElement;i++)
    {
        resultPtr->element[i].i=paraData[i][0];
        resultPtr->element[i].j=paraData[i][1];
        resultPtr->element[i].e=paraData[i][2];
    }
    return resultPtr;
}

void printCompressedMatrix(CompressedMatrixPtr paraPtr)
{
    for(int i=0;i<paraPtr->num;i++)
    {
        printf("(%d,%d):%d\r\n",paraPtr->element[i].i,paraPtr->element[i].j,paraPtr->element[i].e);
    }
}

CompressedMatrixPtr transposeCompressedMatrix(CompressedMatrixPtr paraPtr)
{
    int i,tempCol,tempPosition;
    int* tempColCounts=(int*)malloc(paraPtr->col*sizeof(int));
    int* tempOffSet=(int*)malloc(paraPtr->col*sizeof(int));

    for(i=0;i<paraPtr->col;i++)
    {
        tempColCounts[i]=0;
    }

    CompressedMatrixPtr resultPtr=(CompressedMatrixPtr)malloc(sizeof(struct CompressedMatrix));
    resultPtr->row=paraPtr->col;
    resultPtr->col=paraPtr->row;
    resultPtr->num=paraPtr->num;

    resultPtr->element=(TriplePtr)malloc(paraPtr->num*sizeof(struct Triple));

    for(i=0;i<paraPtr->num;i++)
    {
        tempColCounts[paraPtr->element[i].j] ++;
    }
    tempOffSet[0]=0;
    for(i=1;i<paraPtr->col;i++)
    {
        tempOffSet[i]=tempOffSet[i-1]+tempColCounts[i-1];
        printf("tempOffSet[%d]=%d\r\n",i,tempOffSet[i]);
    }
    for(i=0;i<paraPtr->num;i++)
    {
        tempCol=paraPtr->element[i].j;
        tempPosition=tempOffSet[tempCol];
        resultPtr->element[tempPosition].i=paraPtr->element[i].j;
        resultPtr->element[tempPosition].j=paraPtr->element[i].i;
        resultPtr->element[tempPosition].e=paraPtr->element[i].e;

        tempOffSet[tempCol]++;
    }
    return resultPtr;
}

void compressedMatrixTest()
{
    CompressedMatrixPtr tempPtr1,tempPtr2;

    int i,j,tempElement;

    tempElement=4;
    int** tempMatrix1=(int**)malloc(tempElement*sizeof(int*));
    for(i=0;i<tempElement;i++)
    {
        tempMatrix1[i]=(int*)malloc(3*sizeof(int));
    }

    int tempMatrix2[4][3]={{0,0,2},{0,2,3},{2,0,5},{2,1,6}};
    for(i=0;i<tempElement;i++)
    {
        for(j=0;j<3;j++)
        {
            tempMatrix1[i][j]=tempMatrix2[i][j];
        }
    }
    tempPtr1=initCompressedMatrix(2,3,4,tempMatrix1);

    printf("After initialization.\r\n");
    printCompressedMatrix(tempPtr1);

    tempPtr2=transposeCompressedMatrix(tempPtr1);
    printf("After transpose.\r\n");
    printCompressedMatrix(tempPtr2);
}
int main()
{
    compressedMatrixTest();
    return 0;
}

7.样例输出

After initialization.
(0,0):2
(0,2):3
(2,0):5
(2,1):6
tempOffSet[1]=2
tempOffSet[2]=3
After transpose.
(0,0):2
(0,2):5
(1,2):6
(2,0):3

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ALuoJi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值