noj数据结构稀疏矩阵的加法十字链表_看数据结构写代码(21) 稀疏矩阵(十字链表方式)...

本文介绍了如何使用C++实现稀疏矩阵的十字链表数据结构,并详细讲解了初始化、销毁、插入、删除以及加法操作的过程。在实际操作中,注意避免多次释放同一内存空间导致的_CrtIsValidHeapPointer异常。代码示例展示了完整的十字链表操作流程。
摘要由CSDN通过智能技术生成

写完 这个样例,花费了 我不少时间。大部分时间 花费在 调试 内存问题上。

比如在销毁十字链表时。多次释放节点空间,造成 _CrtIsValidHeapPointer(pUserData) 异常。

当使用malloc 分配 一个 空间时,会将这个空间的起始地址和长度 加到一个链表中去。free(p)的时候

,会从 链表里 查找 是否 有 这个地址空间,找到了就将这个节点从链表中删除。_CrtIsValidHeapPointer(pUserData)  这个函数 正是 检查 这个空间是否 在链表里,若在,返回 true,否则返回

flase,。

多次 释放节点空间,必然 造成 _CrtIsValidHeapPointer(pUserData) 异常。

仅仅要释放的 不是 分配的起始 地址 都会 报 这个异常。

还有

一个 地方,就是 使用了 释放的 空间的数据。

c/c++ 内存问题。是个 头疼的问题。

以下 进入 正题:

稀疏矩阵 的 十字链表 方式,是 给 全部的行 和 列 都 当成 一个 链表 来处理。

第 i 行 j列的 非0 节点,既在 第 i行的链表上,又在 第 j列的 链表上,所以 叫 十字链表。

结构图例如以下:

以下 上代码

欢迎指出代码不足

// CrossList.cpp : 定义控制台应用程序的入口点。

//稀疏矩阵的十字链表实现

#include "stdafx.h"

#include

typedef int ElementType;

enum E_State

{

E_State_Error = 0,

E_State_Ok = 1,

};

struct MatrixNode

{

int row;

int col;

ElementType data;

MatrixNode * rightNext;

MatrixNode * downNext;

};

MatrixNode * makeNode(int row,int col,ElementType data){

MatrixNode * newNode = (MatrixNode *) malloc(sizeof(MatrixNode));

if (newNode != NULL)

{

newNode->row = row;

newNode->col = col;

newNode->data = data;

newNode->rightNext = NULL;

newNode->downNext = NULL;

}

return newNode;

}

//十字链表

struct CrossList

{

MatrixNode ** rowHead;

MatrixNode ** colHead;

int rowNum;

int colNum;

int totalNum;

};

E_State listInit(CrossList * list,int row,int col){

list->rowHead = (MatrixNode**)malloc(sizeof(MatrixNode*) * row);

list->colHead = (MatrixNode**)malloc(sizeof(MatrixNode*) * col);

if (list->rowHead && list->colHead)

{

list->rowNum = row;

list->colNum = col;

list->totalNum = 0;

//建立头指针节点

for (int i = 0; i < row; i++)

{

list->rowHead[i] = makeNode(-1,-1,-1);

if (list->rowHead[i] == NULL)

{

return E_State_Error;

}

}

for (int i = 0; i < col; i++)

{

list->colHead[i] = makeNode(-1,-1,-1);

if (list->colHead[i] == NULL)

{

return E_State_Error;

}

}

return E_State_Ok;

}

return E_State_Error;

}

//销毁十字链表

void listDestory(CrossList * list){

//销毁链表节点

for (int i = 0; i < list->rowNum; i++)

{

MatrixNode * head = list->rowHead[i];

MatrixNode * next = head->rightNext;

while (next != NULL)

{

MatrixNode * freeNode = next;

next = next->rightNext;

free(freeNode);

}

//别忘了销毁头节点

free(head);

}

for (int i = 0; i < list->colNum; i++)

{

MatrixNode * head = list->colHead[i];

free(head);

/*销毁了两遍,呵呵

MatrixNode * next = head->downNext;

while (next != NULL)

{

MatrixNode * freeNode = next;

next = next->downNext;

free(freeNode);

}*/

}

free(list->colHead);

free(list->rowHead);

list->colHead = NULL;

list->rowHead = NULL;

list->rowNum = 0;

list->colNum = 0;

list->totalNum = 0;

}

//在 row 行 col 列 插入 一个 data 元素(从 0行。0列 開始)

E_State listInsert(CrossList * list,ElementType data,int row,int col){

if (row < 0 || row >= list->rowNum || col >= list->colNum || col < 0)

{

return E_State_Error;

}

MatrixNode * newNode = makeNode(row,col,data);

if (newNode != NULL)

{

//增加行链表

MatrixNode * pre = list->rowHead[row];

MatrixNode * next = pre->rightNext;

while (next != NULL)//寻找 第一个列值 小于 col 的节点

{

if (next->col > col)

{

break;

}

pre = next;

next = next ->rightNext;

}

newNode->rightNext = pre->rightNext;

pre->rightNext = newNode;

//加到列链表

pre = list->colHead[col];

next = pre->downNext;

while (next != NULL)//寻找 第一个列值 小于 col 的节点

{

if (next->row > row)

{

break;

}

pre = next;

next = next ->downNext;

}

newNode->downNext = pre->downNext;

pre->downNext = newNode;

list->totalNum ++;

return E_State_Ok;

}

return E_State_Error;

}

//row ,col 从 0行 0 列 開始

E_State listDelete(CrossList * list,int row,int col,ElementType * delData){

if (row >= list->rowNum || row < 0 || col >= list->colNum || col <0)

{

return E_State_Error;

}

*delData = 0;

//查找行链表

MatrixNode * pre = list->rowHead[row];

MatrixNode * next = pre->rightNext;

while (next != NULL)

{

if (next->col == col)

{

pre->rightNext = next->rightNext;

break;

}

else if(next->col > col)// 删除的节点 值域为0

{

return E_State_Ok;

}

pre = next;

next = next->rightNext;

}

//查找列链表

pre = list->colHead[col];

next = pre->downNext;

while (next != NULL)

{

if (next->row == row)

{

pre->downNext = next->downNext;

*delData = next->data;

list->totalNum --;

//在查找完了 列链表之后 才干 释放 空间,要不 会内存 错误.

free(next);

break;

}

else if(next->row > row)// 删除的节点 值域为0

{

return E_State_Ok;

}

pre = next;

next = next->downNext;

}

return E_State_Ok;

}

//list1 = list1 + list2

E_State listAdd(CrossList * list1,CrossList list2){

if (list1->rowNum != list2.rowNum || list1->colNum != list2.colNum)

{

return E_State_Error;

}

for (int row = 0; row < list1->rowNum; row++)

{

MatrixNode * next1 = list1->rowHead[row]->rightNext;

MatrixNode * next2 = list2.rowHead[row]->rightNext;

while (next1 && next2)

{

int col1 = next1->col;

int col2 = next2->col;

if (col1 == col2)//元素 同行 同列

{

ElementType sum = next1->data + next2->data;

if (sum == 0)//相加为0

{

ElementType del;

next1 = next1->rightNext;//跟下一句颠倒过来。会有内存错误

listDelete(list1,row,col1,&del);

}

else//相加不为0

{

next1->data = sum;

next1 = next1->rightNext;

}

next2 = next2->rightNext;

}

else if(col1 < col2)//元素1 小于 元素2 的 列

{

next1 = next1->rightNext;

}

else//元素1 大于 元素2的列,插入元素2

{

listInsert(list1,next2->data,row,col2);

next2 = next2->rightNext;

}

}

//插入剩余的 next2 元素

while (next2 != NULL )

{

listInsert(list1,next2->data,row,next2->col);

next2 = next2->rightNext;

}

}

return E_State_Ok;

}

// list1 = list1 - list2

E_State listSub(CrossList * list1,CrossList list2){

if (list1->rowNum != list2.rowNum || list1->colNum != list2.colNum)

{

return E_State_Error;

}

for (int i = 0; i < list2.rowNum; i++)

{

MatrixNode * next = list2.rowHead[i]->rightNext;

while (next != NULL)

{

next->data = -next->data;

next = next->rightNext;

}

}

return listAdd(list1,list2);

}

//list3 = list1 * list2

E_State listMult(CrossList list1, CrossList list2,CrossList * list3){

if (list1.colNum != list2.rowNum)

{

return E_State_Error;

}

listInit(list3,list1.rowNum,list2.colNum);

for (int row = 0; row < list1.rowNum; row++)

{

for (int col = 0; col < list2.colNum; col++)

{

MatrixNode * nextCol2 = list2.colHead[col]->downNext;

ElementType mul = 0;

while (nextCol2)

{

MatrixNode * nextRow1 = list1.rowHead[row]->rightNext;

while (nextRow1)

{

if (nextRow1->col == nextCol2->row)

{

mul += nextRow1 -> data * nextCol2 ->data;

}

nextRow1 = nextRow1->rightNext;

}

nextCol2 = nextCol2->downNext;

}

if (mul != 0)

{

listInsert(list3,mul,row,col);

}

}

}

return E_State_Ok;

}

void listTraverse(CrossList list){

printf("--------------------遍历開始-----------------\n");

for (int i = 0; i < list.rowNum; i++)

{

MatrixNode * next = list.rowHead[i]->rightNext;

while (next != NULL)

{

printf("%d行 %d列 : %d\n",next->row+1,next->col+1,next->data);

next = next->rightNext;

}

}

printf("--------------------遍历结束------------------\n");

}

int initData[5][10] = {

{1,0,0,0,0,0,0,0,0,0},

{0,0,2,0,0,0,0,0,5,0},

{0,0,0,3,0,0,0,0,0,0},

{0,2,0,0,0,0,0,0,0,0},

{1,0,0,0,0,0,0,0,0,9},

};

int initAddData[5][10]= {

{1,0,0,0,3,0,0,0,0,0},

{0,0,2,0,4,0,0,0,5,0},

{0,0,0,3,0,0,0,0,0,0},

{0,2,0,0,2,0,0,0,0,0},

{1,0,0,0,1,0,0,0,0,9},

};

int initData2 [10][2] = {

{1,0},

{0,0},

{0,0},

{0,0},

{0,0},

{0,6},

{0,0},

{0,0},

{5,0},

{0,0},

};

int _tmain(int argc, _TCHAR* argv[])

{

//初始化数据

printf("--------------------矩阵1------------\n");

CrossList list1;

listInit(&list1,5,10);

for (int i = 0; i < 5; i++)

{

for (int j = 0; j < 10; j++)

{

int data = initData[i][j];

if (data != 0)

{

listInsert(&list1,data,i,j);

}

}

}

listTraverse(list1);

printf("--------------------矩阵2------------\n");

CrossList list2;

listInit(&list2,5,10);

for (int i = 0; i < 5; i++)

{

for (int j = 0; j < 10; j++)

{

int data = initAddData[i][j];

if (data != 0)

{

listInsert(&list2,data,i,j);

}

}

}

listTraverse(list2);

printf("--------------------矩阵1 = 矩阵1 + 矩阵2------------\n");

listAdd(&list1,list2);

listTraverse(list1);

printf("--------------------矩阵1 = 矩阵1 - 矩阵2------------\n");

listSub(&list1,list2);

listTraverse(list1);

printf("--------------------矩阵3------------\n");

CrossList list3;

listInit(&list3,10,2);

for (int i = 0; i < 10; i++)

{

for (int j = 0; j < 2; j++)

{

int data = initData2[i][j];

if (data != 0)

{

listInsert(&list3,data,i,j);

}

}

}

listTraverse(list3);

printf("--------------------矩阵4 = 矩阵1 * 矩阵3------------\n");

CrossList list4;

listMult(list1,list3,&list4);

listTraverse(list4);

//释放内存空间

listDestory(&list1);

listDestory(&list2);

listDestory(&list3);

listDestory(&list4);

return 0;

}执行截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值