实现三元组表示的两个稀疏矩阵的加法_数据结构的实践心得(通过两个双链表实现的稀疏矩阵十字链表管理:SparseMatrix)...

本文介绍了使用双链表实现稀疏矩阵的方法,包括初始化、动态增删行列、检查是否为空或已满、获取元素、插入更新和删除元素等操作。此外,还提供了深度优先和宽度优先的检索方式。
摘要由CSDN通过智能技术生成

a9acd85978ce1b6cdcc63e04e96b78af.png

头文件(SparseMatrix.h):

#pragma once

#include "doubleLinkList.h"

#define SparseMatrixDATASIZE 3

#define ROWINDEX 0

#define COLINDEX 1

#define DATAINDEX 2

typedef struct

{

doubleLinkList rowLink; // 矩阵双链表(宽度优先)

int rowCount; // 行数

int colCount; // 列数

doubleLinkList colLink; // 矩阵双链表(深度优先)

}sparseMatrix;

// 初始化稀疏矩阵

void initializeSparseMatrix(sparseMatrix *M, int rowCount, int colCount);

// 初始化稀疏矩阵(十字链表:包括宽度优先和深度优先)

void initializeCrossSparseMatrix(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 "SparseMatrix.h"

// 初始化稀疏矩阵

void initializeSparseMatrix(sparseMatrix *M, int rowCount, int colCount)

{

// 判断传入的行数和列数是否有效

if ((rowCount < 1) || (colCount < 1)) exit(-1);

// 初始化矩阵双链表(宽度优先)

initializeDoubleLinkList(&(M->rowLink), SparseMatrixDATASIZE);

// 初始化矩阵双链表(深度优先)

initializeDoubleLinkList(&(M->colLink), SparseMatrixDATASIZE);

M->rowCount = rowCount;

M->colCount = colCount;

doubleElemType elem[SparseMatrixDATASIZE] = { 0, 0, 0 };

// 宽度优先:固定新增一个矩阵坐标为(0,0)的数据值(0)

insertDoubleLinkList(&(M->rowLink), 0, elem);

}

// 初始化稀疏矩阵(十字链表:包括宽度优先和深度优先)

void initializeCrossSparseMatrix(sparseMatrix *M, int rowCount, int colCount)

{

// 初始化稀疏矩阵

initializeSparseMatrix(M, rowCount, colCount);

doubleElemType elem[SparseMatrixDATASIZE] = { 0, 0, 0 };

// 深度优先:固定新增一个矩阵坐标为(0,0)的数据值(0)

insertDoubleLinkList(&(M->colLink), 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.rowLink.len <= 0);

}

// 矩阵是否已经满,满则返回1,否则返回0

int isFullSparseMatrix(sparseMatrix M)

{

return (M.rowLink.len >= (M.rowCount * M.colCount));

}

// 矩阵的长度,即实际存储元素的个数

int lengthSparseMatrix(sparseMatrix M)

{

return M.rowLink.len;

}

// 矩阵的最大数量

int maxSizeSparseMatrix(sparseMatrix M)

{

return (M.rowCount * M.colCount);

}

// 取得矩阵坐标的数据值(深度优先)

doubleElemType getDataSparseMatrixCol(sparseMatrix M, int rowIndex, int colIndex)

{

// 坐标位置不合理

if ((rowIndex < 0) || (colIndex < 0) || (rowIndex >= M.rowCount) || (colIndex >= M.colCount)) return 0;

// 定义一个doubleNode类型的指针,首先指向头节点(深度优先)

doubleNode *p = M.colLink.head;

// 进行链表的逐个链接获取

while (p)

{

if (colIndex >(int)p->data[COLINDEX])

{

// 指向下一个链表节点

p = p->next;

}

else if (colIndex < (int)p->data[COLINDEX])

{

// 没有找到匹配的数据

return 0;

}

else if (rowIndex >(int)p->data[ROWINDEX])

{

// 指向下一个链表节点

p = p->next;

}

else if (rowIndex < (int)p->data[ROWINDEX])

{

// 没有找到匹配的数据

return 0;

}

else

{

// 矩阵坐标匹配,返回数据值

return p->data[DATAINDEX];

}

// 重新链接到头节点(深度优先),没有找到匹配的数据

if (p == M.colLink.head) return 0;

}

return 0;

}

// 取得矩阵坐标的数据值

doubleElemType getDataSparseMatrix(sparseMatrix M, int rowIndex, int colIndex)

{

// 坐标位置不合理

if ((rowIndex < 0) || (colIndex < 0) || (rowIndex >= M.rowCount) || (colIndex >= M.colCount)) return 0;

// 比较(宽度优先)和(深度优先)检索的数据大小

if ((rowIndex * M.colCount + colIndex) > (colIndex * M.rowCount + rowIndex))

{

// 取得矩阵坐标的数据值(深度优先)

if (M.colLink.head) return getDataSparseMatrixCol(M, rowIndex, colIndex);

}

// 定义一个doubleNode类型的指针,首先指向头节点

doubleNode *p = M.rowLink.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.rowLink.head) return 0;

}

return 0;

}

// 新增或更新矩阵坐标的数据值

int insertSparseMatrix(sparseMatrix *M, int rowIndex, int colIndex, doubleElemType e)

{

// 判断初始化的头节点是否有效

if (!M->rowLink.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->rowLink.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->rowLink.head) break;

}

// 移动到上一个节点(在上一个节点之后新增数据),上一个节点的矩阵坐标(X, Y)都小于新增节点的矩阵坐标

p = p->prev;

doubleElemType elem[SparseMatrixDATASIZE] = { rowIndex, colIndex, e };

// 插入矩阵坐标的数据值

if (insertNodeDoubleLinkList(&(M->rowLink), p, elem))

{

// 新增或更新矩阵坐标的数据值(深度优先)

if (M->colLink.head) return insertSparseMatrixCol(M, rowIndex, colIndex, e);

return 1;

}

else

{

return -1;

}

}

// 新增或更新矩阵坐标的数据值(深度优先)

int insertSparseMatrixCol(sparseMatrix *M, int rowIndex, int colIndex, doubleElemType e)

{

// 判断初始化的头节点是否有效(深度优先)

if (!M->colLink.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->colLink.head;

// 进行链表的逐个链接获取

while (p)

{

if (colIndex >(int)p->data[COLINDEX])

{

// 指向下一个链表节点

p = p->next;

}

else if (colIndex < (int)p->data[COLINDEX])

{

// 没有找到匹配的数据,进行新增

break;

}

else if (rowIndex >(int)p->data[ROWINDEX])

{

// 指向下一个链表节点

p = p->next;

}

else if (rowIndex < (int)p->data[ROWINDEX])

{

// 没有找到匹配的数据,进行新增

break;

}

else

{

// 更新数据值

p->data[DATAINDEX] = e;

return 1;

}

// 重新链接到头节点(深度优先),没有找到匹配的数据,进行新增

if (p == M->colLink.head) break;

}

// 移动到上一个节点(在上一个节点之后新增数据),上一个节点的矩阵坐标(X, Y)都小于新增节点的矩阵坐标

p = p->prev;

doubleElemType elem[SparseMatrixDATASIZE] = { rowIndex, colIndex, e };

// 插入矩阵坐标的数据值(深度优先)

if (insertNodeDoubleLinkList(&(M->colLink), p, elem))

{

return 1;

}

else

{

return -1;

}

}

// 删除矩阵坐标的数据节点

int removeSparseMatrix(sparseMatrix *M, int rowIndex, int colIndex)

{

// 判断初始化的头节点是否有效

if (!M->rowLink.head) return -1;

// 坐标位置不合理

if ((rowIndex < 0) || (colIndex < 0) || (rowIndex >= M->rowCount) || (colIndex >= M->colCount)) return -1;

// 不可删除初始化的头节点

if ((rowIndex == 0) && (colIndex == 0)) return -1;

// 定义一个doubleNode类型的指针,首先指向头节点

doubleNode *p = M->rowLink.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->rowLink.head) return -1;

}

// 删除矩阵坐标的数据节点

if (removeNodeDoubleLinkList(&(M->rowLink), tmp) > 0)

{

// 删除矩阵坐标的数据节点(深度优先)

if (M->colLink.head) return removeSparseMatrixCol(M, rowIndex, colIndex);

return 1;

}

else

{

return -1;

}

}

// 删除矩阵坐标的数据节点(深度优先)

int removeSparseMatrixCol(sparseMatrix *M, int rowIndex, int colIndex)

{

// 判断初始化的头节点是否有效(深度优先)

if (!M->colLink.head) return -1;

// 坐标位置不合理

if ((rowIndex < 0) || (colIndex < 0) || (rowIndex >= M->rowCount) || (colIndex >= M->colCount)) return -1;

// 不可删除初始化的头节点

if ((rowIndex == 0) && (colIndex == 0)) return -1;

// 定义一个doubleNode类型的指针,首先指向头节点(深度优先)

doubleNode *p = M->colLink.head;

doubleNode *tmp = NULL;

// 进行链表的逐个链接获取

while (p)

{

if (colIndex >(int)p->data[COLINDEX])

{

// 指向下一个链表节点

p = p->next;

}

else if (colIndex < (int)p->data[COLINDEX])

{

// 没有找到匹配的数据

return -1;

}

else if (rowIndex >(int)p->data[ROWINDEX])

{

// 指向下一个链表节点

p = p->next;

}

else if (rowIndex < (int)p->data[ROWINDEX])

{

// 没有找到匹配的数据

return -1;

}

else

{

// 待删除的数据节点

tmp = p;

break;

}

// 重新链接到头节点(深度优先),没有找到匹配的数据

if (p == M->colLink.head) return -1;

}

// 删除矩阵坐标的数据节点(深度优先)

return removeNodeDoubleLinkList(&(M->colLink), 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.rowLink.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.rowLink.head) return rowElems;

}

return rowElems;

}

// 取得矩阵列索引的数据值列表(深度优先)

doubleElemType* getDataColSparseMatrixCol(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.colLink.head;

// 进行链表的逐个链接获取

while (p)

{

if (colIndex >(int)p->data[COLINDEX])

{

// 指向下一个链表节点

p = p->next;

}

else if (colIndex < (int)p->data[COLINDEX])

{

// 返回列索引的数据值列表

return colElems;

}

else

{

// 列索引匹配,记录数据值

colElems[(int)p->data[ROWINDEX]] = p->data[DATAINDEX];

// 指向下一个链表节点

p = p->next;

}

// 重新链接到头节点(深度优先),返回列索引的数据值列表

if (p == M.colLink.head) return colElems;

}

return colElems;

}

// 取得矩阵列索引的数据值列表

doubleElemType* getDataColSparseMatrix(sparseMatrix M, int colIndex, doubleElemType* colElems)

{

// 取得矩阵列索引的数据值列表(深度优先)

if (M.colLink.head) return getDataColSparseMatrixCol(M, colIndex, colElems);

if (!colElems) return NULL;

// 坐标位置不合理

if ((colIndex < 0) || (colIndex >= M.colCount)) return NULL;

// 初始化数据值列表

memset(colElems, 0, sizeof(doubleElemType) * M.rowCount);

// 定义一个doubleNode类型的指针,首先指向头节点

doubleNode *p = M.rowLink.head;

// 进行链表的逐个链接获取

while (p)

{

if (colIndex == (int)p->data[COLINDEX])

{

// 列索引匹配,记录数据值

colElems[(int)p->data[ROWINDEX]] = p->data[DATAINDEX];

}

// 指向下一个链表节点

p = p->next;

// 重新链接到头节点,返回列索引的数据值列表

if (p == M.rowLink.head) return colElems;

}

return colElems;

}

// 清空稀疏矩阵

void clearSparseMatrix(sparseMatrix *M)

{

// 清空矩阵双链表(宽度优先)

clearDoubleLinkList(&(M->rowLink));

// 清空矩阵双链表(深度优先)

if (M->colLink.head) clearDoubleLinkList(&(M->colLink));

M->rowCount = 0;

M->colCount = 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值