对于压缩存储稀疏矩阵,无论是使用三元组顺序表,还是使用行逻辑链接的顺序表,归根结底是使用数组存储稀疏矩阵。介于数组 "不利于插入和删除数据" 的特点,以上两种压缩存储方式都不适合解决类似 "向矩阵中添加或删除非 0 元素" 的问题。

例如,A 和 B 分别为两个矩阵,在实现 "将矩阵 B 加到矩阵 A 上" 的操作时,矩阵 A 中的元素会发生很大的变化,之前的非 0 元素可能变为 0,而 0 元素也可能变为非 0 元素。对于此操作的实现,之前所学的压缩存储方法就显得力不从心。

本节将学习用十字链表存储稀疏矩阵,该存储方式采用的是 "链表+数组" 结构,如图 1 所示。

图 1 十字链表示意图

可以看到,使用十字链表压缩存储稀疏矩阵时,矩阵中的各行各列都各用一各链表存储,与此同时,所有行链表的表头存储到一个数组(rhead),所有列链表的表头存储到另一个数组(chead)中。

因此,各个链表中节点的结构应如图 2 所示:

图 2 十字链表的节点结构

两个指针域分别用于链接所在行的下一个元素以及所在列的下一个元素。

链表中节点的 C 语言代码表示应为:

typedef struct OLNode{

int i,j;//元素的行标和列标

int data;//元素的值

struct OLNode * right,*down;//两个指针域

}OLNode;

同时,表示十字链表结构的 C 语言代码应为:

#include

#include

typedef struct OLNode

{

int i, j, e; //矩阵三元组i代表行 j代表列 e代表当前位置的数据

struct OLNode *right, *down; //指针域 右指针 下指针

}OLNode, *OLink;

typedef struct

{

OLink *rhead, *chead; //行和列链表头指针

int mu, nu, tu; //矩阵的行数,列数和非零元的个数

}CrossList;

CrossList CreateMatrix_OL(CrossList M);

void display(CrossList M);

int main()

{

CrossList M;

M.rhead = NULL;

M.chead = NULL;

M = CreateMatrix_OL(M);

printf("输出矩阵M:\n");

display(M);

return 0;

}

CrossList CreateMatrix_OL(CrossList M)

{

int m, n, t;

int i, j, e;

OLNode *p, *q;

printf("输入矩阵的行数、列数和非0元素个数:");

scanf("%d%d%d", &m, &n, &t);

M.mu = m;

M.nu = n;

M.tu = t;

if (!(M.rhead = (OLink*)malloc((m + 1) * sizeof(OLink))) || !(M.chead = (OLink*)malloc((n + 1) * sizeof(OLink))))

{

printf("初始化矩阵失败");

exit(0);

}

for (i = 1; i <= m; i++)

{

M.rhead[i] = NULL;

}

for (j = 1; j <= n; j++)

{

M.chead[j] = NULL;

}

for (scanf("%d%d%d", &i, &j, &e); 0 != i; scanf("%d%d%d", &i, &j, &e)) {

if (!(p = (OLNode*)malloc(sizeof(OLNode))))

{

printf("初始化三元组失败");

exit(0);

}

p->i = i;

p->j = j;

p->e = e;

//链接到行的指定位置

if (NULL == M.rhead[i] || M.rhead[i]->j > j)

{

p->right = M.rhead[i];

M.rhead[i] = p;

}

else

{

for (q = M.rhead[i]; (q->right) && q->right->j < j; q = q->right);

p->right = q->right;

q->right = p;

}

//链接到列的指定位置

if (NULL == M.chead[j] || M.chead[j]->i > i)

{

p->down = M.chead[j];

M.chead[j] = p;

}

else

{

for (q = M.chead[j]; (q->down) && q->down->i < i; q = q->down);

p->down = q->down;

q->down = p;

}

}

return M;

}

void display(CrossList M) {

for (int i = 1; i <= M.nu; i++)

{

if (NULL != M.chead[i])

{

OLink p = M.chead[i];

while (NULL != p)

{

printf("%d\t%d\t%d\n", p->i, p->j, p->e);

p = p->down;

}

}

}

}

运行结果:

输入矩阵的行数、列数和非0元素个数:3 3 3

2 2 3

2 3 4

3 2 5

0 0 0

输出矩阵M:

2       2       3

3       2       5

2       3       4

十字链表 java_十字链表法,十字链表压缩存储稀疏矩阵详解相关推荐

  1. 十字链表法,十字链表压缩存储稀疏矩阵详解

    对于压缩存储稀疏矩阵,无论是使用三元组顺序表,还是使用行逻辑链接的顺序表,归根结底是使用数组存储稀疏矩阵.介于数组 "不利于插入和删除数据" 的特点,以上两种压缩存储方式都不适合解 ...

  2. 不思议迷宫量子计算机,不思议迷宫男巫刷法及男巫的猫形态详解

    不思议迷宫男巫刷法及男巫的猫形态详解,不思议迷宫男巫怎么刷,奥刃阵营,冒险者之森隐藏冈布奥.出站时,携带三张失明术.每俩层抄写一张.进入迷宫时携带一只阿兹猫. 阿兹猫死亡后可无限次复活(消耗100探索 ...

  3. SVM中拉格朗日乘子法、KKT条件、对偶问题详解

    SVM中拉格朗日乘子法.KKT条件.对偶问题详解 创作目的 1.SVM回顾 2.拉格朗日乘子法 3.KKT条件 4.对偶问题 强对偶性证明 总结 创作目的 我是机器学习初学者,目前正在上机器学习课,老 ...

  4. 合并两个有序链表 java_合并两个有序链表

    将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. /*** Definition for singly-linked list.* struct ListN ...

  5. java源码系列:HashMap底层存储原理详解——5、技术本质-原理过程-算法-取模会带来一个什么问题?什么是哈希冲突?为什么要用链表?

    目录 取模会带来一个什么问题? 演示什么是哈希冲突(哈希碰撞)? 为什么要用链表? 其他--布隆过滤器 取模会带来一个什么问题? 好,那同学们这样他能达到一个目的,但是呢,它也会带来的一个问题,那它会 ...

  6. c语言中欧几里得模乘法逆元,扩展欧几里得算法同余方程模m乘法逆元详解

    欧几里德算法: 复习:求最大公约数算法(欧几里得算法.也叫辗转相除法).欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd ...

  7. php生成迷宫图片,PHP实现基于回溯法求解迷宫问题的方法详解

    本文实例讲述了PHP实现基于回溯法求解迷宫问题的方法.分享给大家供大家参考,具体如下: 引言 最近在leetcode上看了些算法题,有些看着很简单的很常用的东西,竟然一下子想不出来怎么求解,比如说:实 ...

  8. OpenCV学习笔记与代码示例(三):张氏标定法标定相机原理及函数详解

    目录 1.张氏标定法基本原理 1.1相机针孔模型 1.2单应矩阵H 1.3求相机内参 1.4求相机外参 1.5优化参数 1.6总结 2.OpenCV实现 2.1特征点检测与靶标坐标初始化 2.2相机标 ...

  9. throws java_基于Java中throw和throws的区别(详解)

    系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 ...

最新文章

  1. @MySQL为表字段添加索引
  2. Linux C编程--网络编程2--面向连接的网络编程
  3. 全球及中国穆斯林食品行业现状调研与竞争策略分析报告2021年版
  4. Jni Helloworld
  5. 高级筛选的以公式结果为条件
  6. 【数据库学习】——windows、MySQL构建新闻管理系统(控制台版)
  7. [js] 举例说明面向对象编程有什么缺点?
  8. (pytorch-深度学习)实现残差网络(ResNet)
  9. mysql zrm_mysql数据库备份—ZRM
  10. Axure RP Extension for Chrome经常损坏
  11. springboot 设置默认访问index.html_【SpringBoot WEB系列】WebFlux静态资源配置与访问
  12. 清理电脑文件夹中的Thumbs.db文件
  13. 关系抽取综述及相关顶会论文介绍
  14. keil5图标变成白色_图标设计全方位解读
  15. java通过银行账号获取银行名称
  16. cocos 微信小游戏 加载云端资源
  17. DoEvents的用法
  18. ie怎么修改html代码,如何修改IE默认网页源码查看器
  19. UE4移动组件详解(二)——移动同步机制
  20. python爬取软件内数据_各种数据爬取工具爬虫合集整理

热门文章

  1. 简单的计算机英语文章,简单的英语小短文欣赏
  2. python获取手机号码归属地_Python批量获取并保存手机号归属地和运营商的示例
  3. 2017.9.27 书架 思考记录
  4. 2017.9.22 松鼠的聚会 失败总结
  5. 2017.3.14-9.1 玩具取名 失败总结
  6. Bzoj 4422: [Cerc2015]Cow Confinement(线段树+扫描线)
  7. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(11) - 数据可缓存性控制指令
  8. matlab createtask,Matlab批量与createjob
  9. autojs定时可以选定日期吗_微信怎么定时发送朋友圈——软件教程
  10. 用C语言程序实现黎曼和求定积分