图的存储结构—十字链表

图的存储结构:

 

邻接表虽然很好,但也有不足,列如对有向图的处理上,有时候需要在建立一个逆邻接表。

默认的邻接表是关注的顶点的出度和弧尾的,如果我们要关注有向图顶点的入度和弧头,我们就需要在建立个逆邻接表了。

 

所以,有没有可能把邻接表和逆邻接表结合起来呢?

 

十字链表:

 

为此我们要重新定义顶点表节点结构:

         Data

         firstIn

         firstOut

 

firstIn:表示第一个入边表的指针

firstOut:表示第一个出边表的指针

 

然后重新定义边表节点结构:

   tailVex

    headVex

  headLink

    tailLink

 

tailVex:表示弧起点的顶点下标

headVex:表示弧终点的顶点下标

则此边表表示的一条弧(与邻接表的表示一个顶点所不同)

这样不添加fistIn入度的信息就和邻接表是相似的了。(只是边表表示的一个弧而不是一个顶点)。



给上面的图解添加入度的信息(firstIn)




 

V0顶点的入度为v1->v0,则v0的firstIn的指针域指向v1->v0这条弧,v0顶点的第二个入度为v2->v0,则表示v1->v0这条弧的链表的headLink指针域指向v0的下个入度v2->v0弧,

因为v0顶点除此之外在没有入度了,则表示v2->v0弧的链表的入度指针域为空指针。

 

V1顶点的入度为v2->v1,则v1的firstIn指针指向v2->v1这条弧,由于v1顶点只有一条入度弧,则v2->v1弧的链表的headLink指针域为空。

 

同理v2的入度为v1-v2,则指向v1-v2弧的链表

 

总结:

 

顶点数组:数组元素为一个结构体,数据元素,两个指针域,firstOut指向出度链表

firstIn指向入度。

边表(表示一个弧):为一个单链表,元素为一个4个元素的结构体,tailVex为该弧的起始顶点,headVex为该弧的终点顶点。

tailLink指针域:指向该顶点的下一个出度。

headLink指针域:指向该顶点的下个入度。

 

### 西工大 NOI 数据结构 十字链表 矩阵相乘 实现方法 十字链表是一种特殊的稀疏矩阵存储方式,它通过双向链表的形式来表示矩阵中的非零元素。这种方式可以高效地处理大规模稀疏矩阵的操作,比如加法、减法以及乘法。 #### 十字链表简介 十字链表的核心思想是利用两个方向的指针分别指向同一行和同一列的下一个非零元素。每个节点通常包含五个字段:`row`(行号)、`col`(列号)、`value`(数值)、`right`(右向指针)和 `down`(下向指针)。这种结构使得我们可以快速定位到某个特定位置上的非零元素,并且能够方便地遍历整个矩阵[^1]。 #### 稀疏矩阵相乘原理 假设我们有两个稀疏矩阵 A 和 B 需要计算它们的乘积 C=A×B,则新矩阵 C 的大小为 (A 的行数 × B 的列数)。如果采用传统的二维数组形式来进行运算,在面对高维或者低密的情况下效率会变得极差;而借助十字链表则可以在一定程上优化这一过程: - **初始化阶段**: 创建一个新的空白十字链表用于保存结果矩阵 C; - **逐行列扫描匹配**: 对于每一个存在于 A 中的有效元组 `(i,j,v)` ,找到所有满足条件 `k=j` 并且属于 B 的有效元组 `(j,l,w)` 后累加对应的位置 c[i][l]+=(v*w); - **更新链接关系**: 将新增的数据项插至适当位置保持原有顺序不变. 以下是基于以上描述的一个简单伪代码框架: ```cpp // 定义结点类 struct Node { int row, col; double value; Node* right; Node* down; }; Node* multiplySparseMatrix(Node* headA, Node* headB){ // ... 初始化逻辑 ... for(auto nodeInA : traverseByRow(headA)){ auto currentColInB = findFirstNonZeroColumn(nodeInA->col, headB); while(currentColInB != nullptr){ addValueToResult( resultHead, nodeInA->row, currentColInB->col, nodeInA->value * currentColInB->value ); currentColInB = nextNonZeroSameColumnAsCurrentOne(currentColInB); } } return resultHead; } ``` 此段程序展示了如何使用十字链表完成两份稀疏矩阵之间的乘法操作。其中涉及到了几个辅助函数如 `traverseByRow`, `findFirstNonZeroColumn`, `nextNonZeroSameColumnAsCurrentOne` 及 `addValueToResult`. 这些都需要依据具体需求自行编写实现细节[^2]. #### 注意事项 当实际编码时需要注意边界情况处理,例如某一行完全没有非零值的情况等等。另外由于涉及到大量动态内存分配与释放工作所以也要格外小心防止出现野指针等问题发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值