稀疏矩阵——三元组十字链表的C语言实现

粗浅学习稀疏矩阵——三元组十字链表。
代码实现了新建矩阵、矩阵相加、矩阵逆置和矩阵打印在屏幕上。
惭愧于命名规范和编程水平,不足的地方请大牛们多多指教:
直接上代码
crosslist.h

#ifndef _crosslist_h_
#define _crosslist_h_
#include "malloc.h"
#include "stdio.h"
typedef struct OLNode
{
	int row, col;
	int value;
	struct OLNode *right;
	struct OLNode *down;
}OLNode, *OLink;

typedef struct
{
	OLink *row_head;		//行指针
	OLink *col_head;		//列指针
	int row, column;		//用于标识当前矩阵的行和列
}CrossList;
//创建一个矩阵
int CreateCrossList(CrossList *M, int row, int column)
{
	int  i;
	if (row <= 0 || column <= 0)
		return 0;
	//采用十字链表储存结构,创建稀疏矩阵
	M->row = row;
	M->column = column;
	if (!(M->row_head = (OLink *)malloc((row + 1)*sizeof(OLink))))
		return 0;
	if (!(M->col_head = (OLink *)malloc((column + 1)*sizeof(OLink))))
		return 0;
	//对行表头和列表头赋值为空
	for (i = 0; i <= row; i++)
		M->row_head[i] = NULL;
	for (i = 0; i <= column; i++)
		M->col_head[i] = NULL;
	return 1;
}
//添加一个元素
void addCrossList(CrossList *M, int row, int column, int value)
{
	OLNode* head;
	OLNode* q;
	OLNode* pre;
	q = (OLNode *)malloc(sizeof(OLNode));
	q->row = row;
	q->col = column;
	q->value = value;
	q->right = NULL;
	q->down = NULL;
	//先找行如果有标识出来,头指针为空
	if ((M->row_head)[row] == NULL)
	{
		head = (OLNode *)malloc(sizeof(OLNode));
		(M->row_head[row]) = head;
		head->down = NULL;
		head->value = -1;
		head->right = q;
		q->right = NULL;
	}
	else
	{
		pre = M->row_head[row];
		while (pre->right && pre->right->col <= column)
			pre = pre->right;
		//判断是否已存在该点,若有则相加即可
		if (pre->row == row && pre->col == column)
		{
			pre->value += value;
			return;
		}
		q->right = pre->right;
		pre->right = q;
	}

	//再插列如果有标识出来
	if (M->col_head[column] == NULL)
	{
		M->col_head[column] = (OLNode *)malloc(sizeof(OLNode));
		M->col_head[column]->down = NULL;
		M->col_head[column]->down = q;
		q->down = NULL;
	}
	else
	{
		for (pre = M->col_head[column]->down; pre->down &&pre->down->row < row; pre = pre->down);
		q->down = pre->down;
		pre->down = q;
	}

}
//按坐标(x,y)将每个值打印出来
void printAll(CrossList M)
{
	int i, row, col;
	row = M.row;
	col = M.column;
	OLNode* q = NULL;
	for (i = 0; i <= row; i++)
	{
		//天坑!若为空,也就不能得到->right
		if (M.row_head[i] == NULL)
			continue;
		for (q = M.row_head[i]->right; q != NULL; q = q->right)
			printf("(%d,%d)=%d    ", q->row, q->col, q->value);
		printf("\n");
	}
	printf("\n");
}

//按坐标(x,y)将每个值打印出来
void printAll2(CrossList M)
{
	int i, row, col;
	row = M.row;
	col = M.column;
	OLNode* q = NULL;
	for (i = 0; i <= col; i++)
	{
		if (M.col_head[i] == NULL)
			continue;
		for (q = M.col_head[i]->down; q != NULL; q = q->down)
			printf("(%d,%d)=%d    ", q->row, q->col, q->value);
		printf("\n");
	}
	printf("\n");
}

//N = N+M,矩阵相加,这里代码要添上对同型矩阵的判断,懒癌。。。
void add(CrossList *N, CrossList M)
{
	int i;
	OLNode* q = NULL;
	for (i = 0; i < M.row; i++)
	{
		if (M.row_head[i] == NULL)
			continue;
		for (q = M.row_head[i]->right; q != NULL; q = q->right)
			addCrossList(N, q->row, q->col, q->value);
	}
}

//矩阵逆置
int transpose(CrossList *M)
{
	OLink *trow, *tcol;
	OLNode *q, *x;
	int i, temp;
	if (!(trow = (OLink *)malloc((M->column + 1)*sizeof(OLink))))
		return 0;
	if (!(tcol = (OLink *)malloc((M->row + 1)*sizeof(OLink))))
		return 0;
	for (i = 0; i <= M->column; i++)
	{
		//对应行的空指针转成列指针
		if (M->col_head[i] == NULL)
		{
			trow[i] = NULL;
			continue;
		}
		//赋列表头给新行表头
		trow[i] = M->col_head[i];
		x = trow[i]->right;
		trow[i]->right = trow[i]->down;
		trow[i]->down = x;
	}
	for (i = 0; i <= M->row; i++)
	{
		//对应列的空指针转成行指针
		if (M->row_head[i] == NULL)
		{
			tcol[i] = NULL;
			continue;
		}
		//赋行表头给新列表头
		tcol[i] = M->row_head[i];
		x = tcol[i]->right;
		tcol[i]->right = tcol[i]->down;
		tcol[i]->down = x;
	}
	for (i = 0; i < M->row; i++)
	{
		if (M->row_head[i] == NULL)
			continue;
		for (q = M->row_head[i]->down; q != NULL; q = q->down)
		{
			//交换行列号
			temp = q->row;
			q->row = q->col;
			q->col = temp;
			//交换行列指针
			x = q->down;
			q->down = q->right;
			q->right = x;
		}
	}
	//释放指针数组
	free(M->col_head);
	free(M->row_head);
	M->col_head = tcol;
	M->row_head = trow;
	return 1;
}
#endif

main.c

#include "stdio.h"
#include "crosslist.h"
int main(void)
{
	CrossList cr1, cr2;
	printf("创建矩阵1\n");
	CreateCrossList(&cr1, 15,15);
	addCrossList(&cr1, 4, 4, 22);
	addCrossList(&cr1, 3, 5, 24);
	addCrossList(&cr1, 4, 5, 23);
	addCrossList(&cr1, 2, 5, 2);
	addCrossList(&cr1, 4, 2, 32);
	printAll(cr1);
	printf("创建矩阵2\n");
	CreateCrossList(&cr2, 15, 15);
	addCrossList(&cr2, 1, 4, 22);
	addCrossList(&cr2, 3, 5, 24);
	addCrossList(&cr2, 4, 5, 23);
	printAll(cr2);
	printf("矩阵2加到矩阵1\n");
	add(&cr1, cr2);
	printAll(cr1);
	printf("矩阵1转置\n");
	transpose(&cr1);
	printAll(cr1);
	getchar();
	return 0;
}

稀疏矩阵——三元组十字链表的C语言实现
感想:在二级指针上 typedef struct OLNode{}*OLink;与OLink *row_head;上纠结了许久,在写转置的过程中指针的乱指、眼瞎让我花了很多时间在调试上,下一次再写需理清思路,考虑周全再下手也不迟。