1 稀疏矩阵仍然是矩阵。既然稀疏矩阵可以用三元组的顺序表或者链表表示,那么普通矩阵当然也可以。先这样考虑,可以减少结构体节点指针域取值的复杂性。
2 顺序表需要预先定义足够大的数组,也占用内存空间。顺序表根据成员数组下标存取数据很快,但插入删除数组元素时移动数据比较多。单链表存储数据,访问时候只能从链表头开始查找,直到找到符合的节点,查找数据慢些,但插入和删除数据节点比较方便。
3对于稀疏矩阵,可以用链表存储其三元组信息,其right成员和down成员互相指向,连接构成十字链表。
4课本插图如下 :
以上插图好理解么?我们再补充一些,以便于理解,比如有下面矩阵,要求生成其十字链表:
矩阵元素值如图所示,每个元素,将来都要以结构体节点的形式存入链表,其各自节点的地址,以其右上角红圈带数字表示,总头节点和4 个小头节点(即行列头节点)地址,以红圈里的大写字母表示,具体如图里文字所示。
5 整个链表设计思路是构成了三个循环链表,每一行的最后一个节点的right成员指向行头节点;每一列的最后一个成员的down成员指向其所在列的列头节点;最后一个行列头结点(取行列数的较大值)的point成员指向总头节点,即红圈里的H。如何判断指针访问到了行尾或者列尾最后一个元素节点呢?当其right或down成员指向行列头结点的时候。小头节点访问到了最后一行或最后一列的判断方法同理,其point域指向了H。
6结构体信息和链表初始化信息如下,这里用到了union共用体,这样做到的好处是只需要建立一种结构体类型就可以表示所有类型的节点:总头节点、行列头节点和数据节点。矩阵里的元素,我们称之为数据节点。
7 学习的难点就在于结构体里面五个成员,三个指针,我们根本不知道哪个指针该指向哪个节点。本文中举例的矩阵,其构成的十字链表信息如下图:
8 图片里每个节点左上角的带圈数字代表了其节点本身的地址。
9程序里,首先建立空的循环链表,逐行扫描整个矩阵,遇到不为0的元素,新建其对应的节点,并将其插入链表,插入位置是依据其行标和列标的有序递增排列,即每次插入,都要从头扫描其待插入的行列链表,以找到其合适的位置,完善其right和down成员信息。本新建数据节点的插入链表方法,会用到大量的循环,可能不是最快的方法,但是是课本里的方法,但能解决问题就好,聊胜于无。而且逻辑很简单,很好理解。毕竟尾插法建立单链表(包括循环单链表)需要多建立一个指向尾节点的指针,对于矩阵有着多行多列,而且考虑更普遍的问题对于任意矩阵,行列数还不确定,需要太多的尾指针了,而且也不好对所有尾指针保持其同步,所以尾插法建表于此处并不合适,当然也不能用头插法建表。
附上第一张草稿,字体不太好,谢谢:
考虑篇幅问题,这是上篇,具体的代码和测试结果,见下篇,思路如此,写好后上传,谢谢。