文章目录
矩阵乘
这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明
一、矩阵乘的计算
矩阵乘这里定义了两个结构体,一个采用动态分配空间,数组长度不定,一个采用静态分配空间。
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