以下是引用有容就大在2012-8-11 14:03:06的发言:
俺在看 写的很好啊 。。。
俺在看 写的很好啊 。。。
哈哈,荣幸之至。



程序代码:#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MAX_ROW 1000 // 矩阵的最大行数
#define MAX_COL 1000 // 矩阵的最大列数
typedef int status;
typedef double elem_type;
typedef struct node
{
elem_type data; // 结点非零元的值
int column; // 结点的列数
struct node *next; // 指向下一结点的指针
}node;
typedef struct head
{
int row; // 头结点的行数
int sum; // 此行拥有的非零元的个数
struct node *right; // 此行的非零结点的指针
}head;
typedef struct matrix
{
head head_array[MAX_ROW]; // 头结点数组
int m_row , m_col; // 矩阵的实际行数 和 列数
}MATRIX;
//////////////////////////////////
// 子函数声明
//////////////////////////////////
MATRIX * Matrix_create(int row, int column); // 创建rows行columns列矩阵,元素初始值为0
void Matrix_free(MATRIX * mat); // 销毁mat矩阵
status Matrix_rows_len(MATRIX * mat); // 获取矩阵mat的行数,mat为空指针时返回0
status Matrix_cols_len(MATRIX * mat); // 获取矩阵mat的列数,mat为空指针时返回0
status Matrix_set(MATRIX * mat, int row,
int column, double value); // 设置mat矩阵第row行第column列的元素值为value,
// 操作成功返回0值,否则返回非0
// 其实相当于插入操作
void Matrix_print(MATRIX *mat); // 以稀疏矩阵的形式输出
elem_type Matrix_get(MATRIX * mat, int row, // 获取mat矩阵第row行第column列的元素值
int column);
MATRIX * Matrix_add(MATRIX * mat1, // 计算两个矩阵相加,返回和矩阵。当两个矩阵不
MATRIX * mat2); // 能作加法运算时返回NULL
MATRIX * Matrix_trans(MATRIX * mat); // 返回mat的转置矩阵
MATRIX * Matrix_mul_real(MATRIX * mat, // 计算矩阵与实数相乘
double a);
MATRIX * Matrix_dot_mul(MATRIX * mat1, //计算两个矩阵的点乘。如果不能作运算返回NULL
MATRIX * mat2);
MATRIX * Matrix_mul(MATRIX * mat1, // 计算两个矩阵相乘,注意是mat1左乘mat2。
MATRIX * mat2); // 如果不能作乘法运算返回NULL
//////////////////////////////////
// 主函数入口
//////////////////////////////////
int main(void)
{
MATRIX *mat1, *mat2, *mat_trans;
MATRIX *mat_add, *mat_dot, *mat_mul;
// create
mat1 = Matrix_create(5, 5);
mat2 = Matrix_create(5, 5);
//set
Matrix_set(mat1, 2, 3, 5);
Matrix_set(mat1, 1, 4, 9);
Matrix_set(mat1, 3, 1, 9);
Matrix_set(mat1, 3, 1, 0);
Matrix_set(mat1, 5, 4, 7);
Matrix_set(mat2, 2, 4, 8);
Matrix_set(mat2, 3, 2, 3);
Matrix_set(mat2, 5, 4, 6);
printf("Original!\n");
Matrix_print(mat1);
Matrix_print(mat2);
printf("Add!\n");
mat_add = Matrix_add(mat1, mat2);
Matrix_print(mat_add);
printf("Trans!\n");
mat_trans = Matrix_trans(mat2);
Matrix_print(mat_trans);
printf("real_mul!\n");
Matrix_mul_real(mat1, 3);
Matrix_print(mat1);
printf("Dot_mul!\n");
mat_dot = Matrix_dot_mul(mat1, mat2);
Matrix_print(mat_dot);
printf("Multiply!\n");
mat_mul = Matrix_mul(mat1, mat2);
Matrix_print(mat_mul);
Matrix_free(mat1);
Matrix_free(mat2);
Matrix_free(mat_add);
Matrix_free(mat_trans);
Matrix_free(mat_dot);
Matrix_free(mat_mul);
system("pause");
return 0;
}
//////////////////////////////////
// 各个子函数的具体实现
//////////////////////////////////
MATRIX * Matrix_create(int row, int column)
{
MATRIX *mat;
int i;
node *p;
mat = (MATRIX *) malloc (sizeof (MATRIX));
mat->m_row = row;
mat->m_col = column;
for (i = 1; i <= mat->m_row; i++)
{
p = (node *)malloc(sizeof(node)); // 每行头结点包含一个node结点
mat->head_array[i].right = p; // 使头结点与开辟的结点联系起来
mat->head_array[i].row = i; // 头结点行数
mat->head_array[i].sum = 0; // 头结点保存的初始非零元个数
mat->head_array[i].right->column = 0; // 设置头结点的列数为0
mat->head_array[i].right->data = 0; // 设置头结点的data数据为0
mat->head_array[i].right->next = NULL; // 初始化next为NULL
}
return mat;
}
//-----------------------------------------
void Matrix_print(MATRIX *mat)
{
int i, j;
node *p;
for (i = 1; i <= mat->m_row; i++)
{
p = mat->head_array[i].right->next; // 指向每行的第一个结点
if (0 == mat->head_array[i].sum)
{
for (j = 1; j <= mat->m_col; j++)
printf("%-5.1f", 0);
}
else{
for (j = 1; j <= mat->m_col; j++)
{
if (NULL != p && p->column == j)
{
printf("%-5.1f", p->data);
p = p->next;
}
else printf("%-5.1f", 0);
}
}
printf("\n");
}
printf("\n");
}
//-------------------------------------------
void Matrix_free(MATRIX * mat)
{
int i;
node *p, *q;
if (NULL == mat) return ;
for (i = 1; i <= mat->m_row; i++)
{
p = mat->head_array[i].right;
while (p != NULL)
{
q = p;
p = p->next;
free(q);
}
}
free(mat);
}
//----------------------------------------------
status Matrix_rows_len(MATRIX * mat) // 获取矩阵mat的行数,mat为空指针时返回0
{
if (NULL == mat)
return 0;
else
return mat->m_row;
}
status Matrix_cols_len(MATRIX * mat) // 获取矩阵mat的列数,mat为空指针时返回0
{
if (NULL == mat)
return 0;
else
return mat->m_col;
}
//------------------------------------------------
elem_type Matrix_get(MATRIX * mat, int row, // 获取mat矩阵第row行第column列的元素值
int column)
{
node *p = mat->head_array[row].right;
while (p->column =! column) p = p->next;
return p->data;
}
//-------------------------------------------------
status Matrix_set(MATRIX * mat, int row,
int column, double value) // 设置mat矩阵第row行第column列的元素值为value,
// 操作成功返回0值,否则返回非0
{
node *p;
node *q, *insert;
if (row > mat->m_row || column > mat->m_col || row < 1 || column < 1)
{
printf("Beyond now!\n");
return -1;
}
p = mat->head_array[row].right;
while (NULL != p && p->column < column) // 寻找适当的位置
{
q = p;
p = p->next;
}
if (NULL == p) // 原来的行中没有非零元 或者插入的元在行的最后
{
insert = (node *)malloc(sizeof(node));
insert->data = value;
insert->next = NULL;
insert->column = column;
q->next = insert;
mat->head_array[row].sum += 1;
return 0;
}
if (NULL != p && p->column == column && value == 0) // 在链中找到一个非零元和要求的位置一样
{ // 并且value = 0
q->next = p->next;
free(p);
mat->head_array[row].sum -= 1; // 行的非零元数量减一
return 0;
}
if (NULL != p && p->column == column && value != 0) // value != 0
{
p->data = value;
return 0;
}
if (NULL != p && p->column != column && value != 0) // 在链中间插入一个新的非零元
{
insert = (node *)malloc(sizeof(node));
q->next = insert;
insert->next = p;
insert->column = column;
insert->data = value;
mat->head_array[row].sum += 1;
return 0;
}
return -1;
}
//------------------------------------------------
MATRIX * Matrix_add(MATRIX * mat1, // 计算两个矩阵相加,返回和矩阵。当两个矩阵不
MATRIX * mat2) // 能作加法运算时返回NULL
{
int i;
MATRIX *mat3 = Matrix_create(mat1->m_col, mat1->m_row);
node *p, *q;
if (mat1->m_col == mat2->m_col && mat1->m_row == mat2->m_row)
{
for (i = 1; i <= mat1->m_row; i++)
{
p = mat1->head_array[i].right->next;
q = mat2->head_array[i].right->next;
while (NULL != p && NULL != q)
{
if (p->column < q->column)
{
Matrix_set(mat3, i, p->column, p->data);
p = p->next;
}
else if (p->column > q->column)
{
Matrix_set(mat3, i, q->column, q->data);
q = q->next;
}
else
{
Matrix_set(mat3, i, p->column, p->data + q->data);
p = p->next;
q = q->next;
}
}
while (NULL != p)
{
Matrix_set(mat3, i, p->column, p->data);
p = p->next;
}
while (NULL != q)
{
Matrix_set(mat3, i, q->column, q->data);
q = q->next;
}
}
return mat3;
}
else
return NULL;
}
//-------------------------------------
MATRIX * Matrix_trans(MATRIX * mat) // 返回mat的转置矩阵
{
MATRIX *mat_trans = Matrix_create(mat->m_col, mat->m_row);
int i; node *p ;
for (i = 1; i <= mat->m_row; i++)
{
p = mat->head_array[i].right->next;
while (NULL != p)
{
Matrix_set(mat_trans, p->column, i, p->data);
p = p->next;
}
}
return mat_trans;
}
//----------------------------
MATRIX * Matrix_mul_real(MATRIX * mat, // 计算矩阵与实数相乘
double a)
{
int i;
node *p;
for (i = 1; i <= mat->m_row; i++)
{
p = mat->head_array[i].right->next;
while (NULL != p)
{
p->data *= a;
p = p->next;
}
}
return mat;
}
//------------------------------------------
MATRIX * Matrix_dot_mul(MATRIX * mat1, //计算两个矩阵的点乘。如果不能作运算返回NULL
MATRIX * mat2)
{
MATRIX *mat_dot = Matrix_create(mat1->m_row, mat1->m_col);
node *p, *q;
int i;
if (mat1->m_col == mat2->m_col && mat1->m_row == mat2->m_row)
{
for (i = 1; i <= mat1->m_row; i++)
{
p = mat1->head_array[i].right->next;
q = mat2->head_array[i].right->next;
while (p != NULL && q != NULL)
{
if (p->column < q->column)
p = p->next;
else if (p->column == q->column)
{
Matrix_set(mat_dot, i, q->column, q->data * p->data);
q = q->next;
p = p->next;
}
else if (p->column > q->column)
q = q->next;
}
}
return mat_dot;
}
else
return NULL;
}
//----------------------------------
MATRIX * Matrix_mul(MATRIX * mat1, // 计算两个矩阵相乘,注意是mat1左乘mat2。
MATRIX * mat2) // 如果不能作乘法运算返回NULL
{
if (mat1->m_col != mat2->m_row)
return NULL;
MATRIX *mat_mul = Matrix_create(mat1->m_row, mat2->m_col);
int i, j; elem_type s[MAX_COL] = {0};
node *p, *q;
for (i = 1; i <= mat1->m_row; i++)
{
for (j = 1; j <= mat2->m_col; j++)
s[j] = 0;
p = mat1->head_array[i].right->next;
while (p != NULL)
{
q = mat2->head_array[p->column].right->next;
while (q != NULL)
{
s[q->column] += p->data * q->data;
q = q->next;
}
p = p->next;
}
for (j = 1; j <= mat2->m_col; j++)
{
if (s[j] != 0)
Matrix_set(mat_mul, i, j, s[j]);
}
}
return mat_mul;
}