头文件(SparseMatrix.h):
#pragma once
#include "doubleLinkList.h"
#define SparseMatrixDATASIZE 3
#define ROWINDEX 0
#define COLINDEX 1
#define DATAINDEX 2
typedef struct
{
doubleLinkList doubleLink; // 矩阵双链表
int rowCount; // 行数
int colCount; // 列数
}sparseMatrix;
// 初始化稀疏矩阵
int initializeSparseMatrix(sparseMatrix *M, int rowCount, int colCount);
// 动态增减矩阵的行列
int addRowColSparseMatrix(sparseMatrix *M, int addRow, int addCol);
// 矩阵为空返回1,否则返回0
int isEmptySparseMatrix(sparseMatrix M);
// 矩阵是否已经满,满则返回1,否则返回0
int isFullSparseMatrix(sparseMatrix M);
// 矩阵的数量,即实际存储元素的个数
int lengthSparseMatrix(sparseMatrix M);
// 矩阵的最大数量
int maxSizeSparseMatrix(sparseMatrix M);
// 取得矩阵坐标的数据值
doubleElemType getDataSparseMatrix(sparseMatrix M, int rowIndex, int colIndex);
// 新增或更新矩阵坐标的数据值
int insertSparseMatrix(sparseMatrix *M, int rowIndex, int colIndex, doubleElemType e);
// 删除矩阵坐标的数据节点
int removeSparseMatrix(sparseMatrix *M, int rowIndex, int colIndex);
// 取得矩阵行索引的数据值列表
doubleElemType* getDataRowSparseMatrix(sparseMatrix M, int rowIndex, doubleElemType* rowElems);
// 取得矩阵列索引的数据值列表
doubleElemType* getDataColSparseMatrix(sparseMatrix M, int colIndex, doubleElemType* colElems);
// 清空矩阵坐标
void clearSparseMatrix(sparseMatrix *M);
程序文件(SparseMatrix.c):
#include
#include
#include "SparseMatrix.h"
// 初始化稀疏矩阵
int initializeSparseMatrix(sparseMatrix *M, int rowCount, int colCount)
{
// 判断传入的行数和列数是否有效
if ((rowCount < 1) || (colCount < 1)) exit(-1);
// 初始化双链表
initializeDoubleLinkList(&(M->doubleLink), SparseMatrixDATASIZE);
M->rowCount = rowCount;
M->colCount = colCount;
doubleElemType elem[SparseMatrixDATASIZE] = { 0, 0, 0 };
// 固定新增一个矩阵坐标为(0,0)的数据值(0)
return insertDoubleLinkList(&(M->doubleLink), 0, elem);
}
// 动态增减矩阵的行列
int addRowColSparseMatrix(sparseMatrix *M, int addRow, int addCol)
{
// 避免减少为空行数或空列数
if ((-addRow >= M->rowCount) || (-addCol >= M->colCount)) return -1;
M->rowCount += addRow;
M->colCount += addCol;
return 1;
}
// 矩阵为空返回1,否则返回0
int isEmptySparseMatrix(sparseMatrix M)
{
return (M.doubleLink.len <= 0);
}
// 矩阵是否已经满,满则返回1,否则返回0
int isFullSparseMatrix(sparseMatrix M)
{
return (M.doubleLink.len >= (M.rowCount * M.colCount));
}
// 矩阵的长度,即实际存储元素的个数
int lengthSparseMatrix(sparseMatrix M)
{
return M.doubleLink.len;
}
// 矩阵的最大数量
int maxSizeSparseMatrix(sparseMatrix M)
{
return (M.rowCount * M.colCount);
}
// 取得矩阵坐标的数据值
doubleElemType getDataSparseMatrix(sparseMatrix M, int rowIndex, int colIndex)
{
// 坐标位置不合理
if ((rowIndex < 0) || (colIndex < 0) || (rowIndex >= M.rowCount) || (colIndex >= M.colCount)) return 0;
// 定义一个doubleNode类型的指针,首先指向头节点
doubleNode *p = M.doubleLink.head;
// 进行链表的逐个链接获取
while (p)
{
if (rowIndex > (int)p->data[ROWINDEX])
{
// 指向下一个链表节点
p = p->next;
}
else if (rowIndex < (int)p->data[ROWINDEX])
{
// 没有找到匹配的数据
return 0;
}
else if (colIndex > (int)p->data[COLINDEX])
{
// 指向下一个链表节点
p = p->next;
}
else if (colIndex < (int)p->data[COLINDEX])
{
// 没有找到匹配的数据
return 0;
}
else
{
// 矩阵坐标匹配,返回数据值
return p->data[DATAINDEX];
}
// 重新链接到头节点,没有找到匹配的数据
if (p == M.doubleLink.head) return 0;
}
return 0;
}
// 新增或更新矩阵坐标的数据值
int insertSparseMatrix(sparseMatrix *M, int rowIndex, int colIndex, doubleElemType e)
{
// 判断初始化的头节点是否有效
if (!M->doubleLink.head) return -1;
// 不可新增或更新“0”数据值
if (e == 0) return -1;
// 坐标位置不合理
if ((rowIndex < 0) || (colIndex < 0) || (rowIndex >= M->rowCount) || (colIndex >= M->colCount)) return -1;
// 定义一个doubleNode类型的指针,首先指向头节点
doubleNode *p = M->doubleLink.head;
// 进行链表的逐个链接获取
while (p)
{
if (rowIndex > (int)p->data[ROWINDEX])
{
// 指向下一个链表节点
p = p->next;
}
else if (rowIndex < (int)p->data[ROWINDEX])
{
// 没有找到匹配的数据,进行新增
break;
}
else if (colIndex > (int)p->data[COLINDEX])
{
// 指向下一个链表节点
p = p->next;
}
else if (colIndex < (int)p->data[COLINDEX])
{
// 没有找到匹配的数据,进行新增
break;
}
else
{
// 更新数据值
p->data[DATAINDEX] = e;
return 1;
}
// 重新链接到头节点,没有找到匹配的数据,进行新增
if (p == M->doubleLink.head) break;
}
// 移动到上一个节点(在上一个节点之后新增数据),上一个节点的矩阵坐标(X, Y)都小于新增节点的矩阵坐标
p = p->prev;
doubleElemType elem[SparseMatrixDATASIZE] = { rowIndex, colIndex, e };
// 插入矩阵坐标的数据值
return insertNodeDoubleLinkList(&(M->doubleLink), p, elem);
}
// 删除矩阵坐标的数据节点
int removeSparseMatrix(sparseMatrix *M, int rowIndex, int colIndex)
{
// 坐标位置不合理
if ((rowIndex < 0) || (colIndex < 0) || (rowIndex >= M->rowCount) || (colIndex >= M->colCount)) return -1;
// 不可删除初始化的头节点
if ((rowIndex == 0) && (colIndex == 0)) return -1;
// 定义一个doubleNode类型的指针,首先指向头节点
doubleNode *p = M->doubleLink.head;
doubleNode *tmp = NULL;
// 进行链表的逐个链接获取
while (p)
{
if (rowIndex > (int)p->data[ROWINDEX])
{
// 指向下一个链表节点
p = p->next;
}
else if (rowIndex < (int)p->data[ROWINDEX])
{
// 没有找到匹配的数据
return -1;
}
else if (colIndex > (int)p->data[COLINDEX])
{
// 指向下一个链表节点
p = p->next;
}
else if (colIndex < (int)p->data[COLINDEX])
{
// 没有找到匹配的数据
return -1;
}
else
{
// 待删除的数据节点
tmp = p;
break;
}
// 重新链接到头节点,没有找到匹配的数据
if (p == M->doubleLink.head) return -1;
}
// 删除矩阵坐标的数据节点
return removeNodeDoubleLinkList(&(M->doubleLink), tmp);
}
// 取得矩阵行索引的数据值列表(函数外部使用完成后,需要及时释放返回值的内存空间)
doubleElemType* getDataRowSparseMatrix(sparseMatrix M, int rowIndex, doubleElemType* rowElems)
{
if (!rowElems) return NULL;
// 坐标位置不合理
if ((rowIndex < 0) || (rowIndex >= M.rowCount)) return NULL;
// 初始化数据值列表
memset(rowElems, 0, sizeof(doubleElemType) * M.colCount);
// 定义一个doubleNode类型的指针,首先指向头节点
doubleNode *p = M.doubleLink.head;
// 进行链表的逐个链接获取
while (p)
{
if (rowIndex > (int)p->data[ROWINDEX])
{
// 指向下一个链表节点
p = p->next;
}
else if (rowIndex < (int)p->data[ROWINDEX])
{
// 返回行索引的数据值列表
return rowElems;
}
else
{
// 行索引匹配,记录数据值
rowElems[(int)p->data[COLINDEX]] = p->data[DATAINDEX];
// 指向下一个链表节点
p = p->next;
}
// 重新链接到头节点,返回行索引的数据值列表
if (p == M.doubleLink.head) return rowElems;
}
return rowElems;
}
// 取得矩阵列索引的数据值列表
doubleElemType* getDataColSparseMatrix(sparseMatrix M, int colIndex, doubleElemType* colElems)
{
if (!colElems) return NULL;
// 坐标位置不合理
if ((colIndex < 0) || (colIndex >= M.colCount)) return NULL;
// 初始化数据值列表
memset(colElems, 0, sizeof(doubleElemType) * M.rowCount);
// 定义一个doubleNode类型的指针,首先指向头节点
doubleNode *p = M.doubleLink.head;
// 进行链表的逐个链接获取
while (p)
{
if (colIndex == (int)p->data[COLINDEX])
{
// 列索引匹配,记录数据值
colElems[(int)p->data[ROWINDEX]] = p->data[DATAINDEX];
}
// 指向下一个链表节点
p = p->next;
// 重新链接到头节点,返回列索引的数据值列表
if (p == M.doubleLink.head) return colElems;
}
return colElems;
}
// 清空矩阵坐标
void clearSparseMatrix(sparseMatrix *M)
{
// 清空双链表
clearDoubleLinkList(&(M->doubleLink));
M->rowCount = 0;
M->colCount = 0;
}