十字链表简介与实现(Java)

图 一、基本概念 1.定义 图G由 顶点集V 和 边集E 组成,记为G = (V,E),其中,V(G)表示图G中顶点的有限非空集,E(G)表示图G中顶点之间的关系(边)的集合。若,V={v1,v2,…,vn},则用 |v| 表示图G中顶点的个数,也称,图G的阶;E = {(u,v)|u∈V,v∈V},用|E|表示图G中边的条数。 注意: 线性表可以是空表,树可以是空树,但图不可以是空图;即,图中不能一... 阅读详情

十字链表简介与实现(Java)

结构

十字链表存储有向图(网)的方式与邻接表有一些相同,都以图(网)中各顶点为首元节点建立多条链表,同时为了便于管理,还将所有链表的首元节点存储到同一数组(或链表)中。

其中,建立个各个链表中用于存储顶点的首元节点结构如图 1 所示:

十字链表中首元节点结构示意图
图1

从图 1 可以看出,首元节点中有一个数据域和两个指针域(分别用 firstin 和 firstout 表示):
firstin 指针用于连接以当前顶点为弧头的其他顶点构成的链表;
firstout 指针用于连接以当前顶点为弧尾的其他顶点构成的链表;
data 用于存储该顶点中的数据;
由此可以看出,十字链表实质上就是为每个顶点建立两个链表,分别存储以该顶点为弧头的所有顶点和以该顶点为弧尾的所有顶点。

注意,存储图的十字链表中,各链表中首元节点与其他节点的结构并不相同,图 1 所示仅是十字链表中首元节点的结构,链表中其他普通节点的结构如图 2 所示:

十字链表中普通节点的结构示意图
图2

从图 2 中可以看出,十字链表中普通节点的存储分为 5 部分内容,它们各自的作用是:
tailvex 用于存储以首元节点为弧尾的顶点位于数组中的位置下标;
headvex 用于存储以首元节点为弧头的顶点位于数组中的位置下标;
hlink 指针:用于链接下一个存储以首元节点为弧头的顶点的节点;
tlink 指针:用于链接下一个存储以首元节点为弧尾的顶点的节点;
info 指针:用于存储与该顶点相关的信息,例如量顶点之间的权值;

比如说,用十字链表存储图 3a) 中的有向图,存储状态如图 3b) 所示:

十字链表存储有向图示意图
图 3

拿图 3 中的顶点 V1 来说,通过构建好的十字链表得知,以该顶点为弧头的顶点只有存储在数组中第 3 位置的 V4(因此该顶点的入度为 1),而以该顶点为弧尾的顶点有两个,分别为存储数组第 1 位置的 V2 和第 2 位置的 V3(因此该顶点的出度为 2)。

对于图 3 各个链表中节点来说,由于表示的都是该顶点的出度或者入度,因此没有先后次序之分。

实现

package test;
public class OListDG {
    int vlen; // 顶点个数
    int elen; // 边个数
    VertexNode[] vertexNodeList; // 顶点数组
    EdgeNode edgeNode;
 
    /**
     * 构造函数
     * @param vexs
     * @param edges
     */
    public OListDG(char[] vexs, char[][] edges) {
        vlen = vexs.length;
        elen = edges.length;
 
        // 初始化顶点,建立顶点表
        vertexNodeList = new VertexNode[vlen];
        for (int i = 0; i < vlen; i++) {
            vertexNodeList[i] = new VertexNode();
            vertexNodeList[i].vertex = vexs[i];
            vertexNodeList[i].firstIn = null;
            vertexNodeList[i].firstOut = null;
        }
 
        // 初始化边,利用头插法建立十字链表
        for (int i = 0; i < elen; i++) {
            EdgeNode edgeNode_1 = new EdgeNode();
            EdgeNode edgeNode_2 = new EdgeNode();
            int vi = getPosition(edges[i][0], vexs);
            int vj = getPosition(edges[i][1], vexs);
             
            edgeNode_1.tailvex = vi;
            edgeNode_1.headvex = vj;
            edgeNode_1.taillink = vertexNodeList[vi].firstOut;
            vertexNodeList[vi].firstOut = edgeNode_1;
            
            edgeNode_2.tailvex = vi;
            edgeNode_2.headvex = vj;
            edgeNode_2.headlink = vertexNodeList[vj].firstIn;
            vertexNodeList[vj].firstIn = edgeNode_2;
 
        }
    }
 
    /**
     *  功能:顶点表结点结构
     *  参数:vertex --> 顶点域,存储顶点信息
     *       firstIn --> 入边表头指针,指向该顶点的入边表中第一个结点
     *       firstOut --> 出边表头指针,指向该顶点的出边表中第一个结点
     */
    private class VertexNode {
        char vertex; 
        EdgeNode firstIn;
        EdgeNode firstOut; 
    }
 
    /**
     *  功能:边表结点
     *  参数:tailvex --> 弧起点在顶点表的下标
     *        headvex --> 弧终点在顶点表的下标
     *        headlink --> 入边表指针域,指向终点相同的下一条边
     *        taillink --> 边表指针域,指向起点相同的下一条边
     */
    private class EdgeNode {
    	int tailvex;
    	int headvex;
    	EdgeNode headlink;
    	EdgeNode taillink;
    }
 
    /**
     *  功能:返回ch位置
     */
    private int getPosition(char ch, char[] vexs) {
        for (int i = 0; i < vlen; i++)
            if (vexs[i] == ch)
                return i;
        return -1;
    }
 
    /**
     *  功能:打印邻接表和逆邻接表
     */
    public void print() {
        System.out.printf("AdjList:\n");
        for (int i = 0; i < vlen; i++) {
            System.out.print(vertexNodeList[i].vertex + "-->");
            if (vertexNodeList[i].firstOut != null) {
                EdgeNode mEdgeNode = new EdgeNode();
                mEdgeNode = vertexNodeList[i].firstOut;
                System.out.print(mEdgeNode.headvex);
                while (mEdgeNode.taillink != null) {
                    mEdgeNode = mEdgeNode.taillink;
                    System.out.print(mEdgeNode.headvex);
                }
                System.out.print("\n");
            } else {
                System.out.print("\n");
            }
        }
        
        System.out.print("----------\n");
        
        System.out.printf("InvAdjList:\n");
        for (int i = 0; i < vlen; i++) {
            System.out.print(vertexNodeList[i].vertex + "<--");
            if (vertexNodeList[i].firstIn != null) {
                EdgeNode mEdgeNode = new EdgeNode();
                mEdgeNode = vertexNodeList[i].firstIn;
                System.out.print(mEdgeNode.tailvex);
                while (mEdgeNode.headlink != null) {
                    mEdgeNode = mEdgeNode.headlink;
                    System.out.print(mEdgeNode.tailvex);
                }
                System.out.print("\n");
            } else {
                System.out.print("\n");
            }
        }
    }
 
    /**
     * 主函数
     */
    public static void main(String args[]) {
    	// 顶点数组
        char[] vexs = {
            'A', 'B', 'C', 'D'
        };
        // 边数组
        char[][] edges = new char[][] {
            {
                'A', 'B'
            }, {
                'A', 'C'
            }, {
                'A', 'D'
            }, {
                'B', 'D'
            }, {
                'C', 'D'
            }
        };
 
        OListDG listUDG = new OListDG(vexs, edges);
        listUDG.print();
    }
}
6.4.图的存储结构-十字链表、邻接多重表 十字链表法只能存储有向图,解决了邻接矩阵法存储有向图时空间复杂度高的问题,同时解决了用邻接表存储有向图时找入边不方便的问题邻接多重表只能存储无向图,解决了邻接矩阵法存储无向图时空间复杂度高的问题,同时解决了邻接表中进行无向图的边或顶点的删除等操作繁琐的问题,也解决了邻接表中在存储无向图时存储冗余的边的问题。 阅读详情

相关推荐

十字链表(Java)

对于有向图来说,邻接表是有缺陷的。关心了出度问题,想要了解入度情况就必须要遍历整个图才能知道。反之也一样。那么,这一节就介绍有向图的一种存储方法,它能将邻接表和逆邻接表结合起来 —— 十字链表。 一、存储结构                                           定义顶点表结点结构: vertex firstIn firstOut

贱贱的梦想 3185

图的存储结构——十字链表

回忆邻接矩阵与邻接表的存储结构,它们都不便于求顶点的出度与入度。为了解决上述两者求出入度的局限性,在此引入十字链表,它可以看成邻接表与逆邻接表的结合,方便求解顶点出入度与获取顶点的出入度边。

m0_72579201的博客 1万+

java 十字链表

结点package crossList; public class OLNode { //非零元素的行和列下标 int row, col; int value; //右边节点指针 OLNode right; //下方节点指针 OLNode down; } package crossList; import cr

xyjikl 1551

图的存储结构-十字链表

图的存储结构,十字链表法 ,带图详细解释创建和存储过程

QQ657205470的博客 6754

数据结构(图)——十字链表(Java实现)

  上次学习了图的邻接表,对于有向图来讲,邻接表是有缺陷的,我们想得到一个顶点的出度,对该顶点的边表遍历即可,需要一个顶点的入度,则需要遍历整个图(逆邻接表解决了入度,解决不了出度)。   这时可以将邻接表跟逆邻接表结合起来就是我们所要说的——十字链表。   这里是个小例子:   图1   内部类定义顶点数组:三个属性分别存放顶点,入边表,出边表    private class Ve...

Advance_的博客 1649

图的十字链表存储法详解

前面介绍了图的邻接表存储法,本节继续讲解图的另一种链式存储结构——十字链表法。 与邻接表不同,十字链表法仅适用于存储有向图和有向网。不仅如此,十字链表法还改善了邻接表计算图中顶点入度的问题。 十字链表存储有向图(网)的方式与邻接表有一些相同,都以图(网)中各顶点为首元节点建立多条链表,同时为了便于管理,还将所有链表的首元节点存储到同一数组(或链表)中。 其中,建立个各个链表中用于存储顶点的首元节点...

数据结构和算法教程(C语言版) 5215

Java实现十字链表

使用Java实现十字链表数据结构 存在着3个自定义类——Graph2、Data2、Vertex2,Graph用于定义图,Data2用于表示顶点节点的Struct,Vertex用于表示弧节点的Struct,定义同教材。 文件1-Graph2.java package orthogonallist; public class Graph2 { //自定义图,可存储50个节点 ...

Caiji的博客 773

Halcon Camera-calibration 相关算子(一)

Halcon Camera-calibration 相关算子介绍

qq_44744164的博客 1366

Java数据结构——十字链表+邻接多重表

{十字链表:打印邻接表,逆邻接表,什么是十字链表,构造有向图}, {邻接多重表,定义,数据结构,Java代码,图例,什么是邻接多重表,意义,邻接多重表的打印,构造函数构造无向图}。

NoBug 2384

自动化专业与嵌入式

在学生时期,我是一个典型的学渣,所以只能选择电气工程、汽修、数控之类的专业。而那些高分的则可以选择计算机,电子商务,通信之类的。这些专业看起来像是蓝领和白领的分界,至今我都觉得这种制度是不人性化的。专业这块根据学生的爱好去选择是最好的,毕竟有兴趣才会”真心”去学习。谁说学渣就学不会编程、学不会金融对吧?不过也罢,在学校能学到东西的毕竟是少数,最近有些大学生发了他们的课程表给我看了下。我感觉学的太广了,什么单片机、c语言、java之类的,导致很多学生学完以后还是很迷茫,不知道自己专业到底是从事什么方向的。所以

m0_71017841的博客 3588

RDKit实战:5分钟搞定药物分子相似性分析(附Python代码)

本文提供了一套基于RDKit的快速药物分子相似性分析实战指南。通过Python代码演示,从环境搭建、分子指纹(如Morgan指纹)计算到Tanimoto相似性排序与可视化验证,帮助研究者在5分钟内完成从海量化合物库中精准筛选潜在活性分子的全流程,提升药物发现效率。

weixin_29193359的博客 314

数据结构Java实现——④数组——>稀疏矩阵十字链表存储法

作者信息 文字描述 1、十字链表的结点的结构 2、十字链表的存储 3、

Stone6762的专栏 4321

ABB机器人将实时坐标发送给西门子PLC的具体方法示例

ABB机器人将实时坐标发送给西门子PLC的具体方法示例

Robot_PLC_HMI_Automation 4914

基于十字链表储存大型路网Java实现

文章首先介绍了图的十字链表表示原理,基于java实现了图的十字链表表示方法,后续将记录相关路径规划算法。

weixin_41399650的博客 792

双重分组进位跳跃进位链

跳跃进位链

qq_62260432的博客 941

(全网最详细教程)康耐视读码器(以DM260S为例子)详细实用步骤

(全网最详细教程)康耐视读码器(以DM260S为例子)详细实用步骤

视觉人机器视觉的博客 7466

java用十字链表实现无向图_实验四:图的实现与应用

20162317袁逸灏 实验四:图的实现与应用实验内容用邻接矩阵十字链表实现无向图中的添加结点删除结点添加边删除边size()isEmpty()广度优先迭代器深度优先迭代器方法实验要求实验1:用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器给出伪代码,产品代码,测试代码(不少于5条测试)...

weixin_29576901的博客 495

稀疏矩阵十字链表类java_数据结构之---C/C++实现稀疏矩阵的十字链表

标签:首先这里介绍什么是矩阵的十字链表,大家可以理解稀疏矩阵是顺序存储的,那么这个就是链式存储的。如图:存储该矩阵那么应该是如下的格式:我们知道稀疏矩阵的三元组存储方式的实现很简单,每个元素有三个域分别是col,row, e。代表了该非零元的行号、列号以及值。那么在十字链表的存储方式下,首先这三个域是肯定少不了的,不然在进行很多操作的时候都要自己使用计数器,很麻烦。而十字链表的形式大家可以理解成每...

weixin_42491664的博客 416

如何让C++程序生成dump文件?生成dump文件的方式有哪些?如何使用Windbg分析dump文件?

本文详细介绍了如何让C++程序生成dump文件、生成dump文件的多种方式以及如何使用Windbg分析dump文件,并给出了对应的实战分析案例,有一定的实战参考价值。

dvlinker的技术专栏 5万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

数据结构 图论02 十字链表详解 代码

数据结构 图论 十字链表详解 代码 阅读之前请了解先了解邻接表邻接表基础 数据结构 上面的数组+链表可以节约一些空间和方便增删,但是我们要计算一个顶点的度还是比较麻烦,十字链表就是解决计算顶点入度(就是有多少条边通向这个节点)的问题 顶点Vertex的结构 data :顶点具体数据信息 firstIn:通向这个顶点的(竖向)边链表的读一个节点 firstOut:通向其他顶点的(横向)边的链表的第一个节点 边edge的结构 fromVertex:箭头出发的顶点(比如A顶点) toVertex:箭

半亩方糖 1830

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

java十字链表存储,图的十字链表存储结构

前面介绍了图的邻接表存储法,本节继续讲解图的另一种链式存储结构——十字链表法。与邻接表不同,十字链表法仅适用于存储有向图和有向网。不仅如此,十字链表法还改善了邻接表计算图中顶点入度的问题。十字链表存储有向图(网)的方式与邻接表有一些相同,都以图(网)中各顶点为首元节点建立多条链表,同时为了便于管理,还将所有链表的首元节点存储到同一数组(或链表)中。其中,建立个各个链表中用于存储顶点的首元节点结构如...

weixin_39755952的博客 186

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

日撸 Java 三百行(37 天: 十字链表)

注意:这里是JAVA自学与了解的同步笔记与记录,如有问题欢迎指正说明

ALBlack的博客 1239

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

对于压缩存储稀疏矩阵,无论是使用三元组顺序表,还是使用行逻辑链接的顺序表,归根结底是使用数组存储稀疏矩阵。介于数组 "不利于插入和删除数据" 的特点,以上两种压缩存储方式都不适合解决类似 "向矩阵中添加或删除非 0 元素" 的问题。例如,A 和 B 分别为两个矩阵,在实现 "将矩阵 B 加到矩阵 A 上" 的操作时,矩阵 A 中的元素会发生很大的变化,之前的非 0 元素可能变为 0,而 0 元素也...

weixin_35820008的博客 311

java十字图_(学习java)用十字链表表示有向图

/*** Author:scorpio0zry** 功能:用java创建十字链表 表示有向图** */public class CrossGraph {int vexL; // 顶点数量int sideL; // 边的数量Vertex[] vertexs; // 顶点数组// 定义顶点结点private class Vertex {char vertex;SideNode firstin; // ...

weixin_30863333的博客 275

稀疏矩阵的十字链表的建立

系数矩阵的十字链表表示法,在我的学习过程中,是个不怎么好掌握的地方,难点就是它的具体建立过程,废话不多说,这是我学习时候的代码,注释很详细,欢迎指正学习和交流 /* 建立稀疏矩阵的十字链表 */ typedef struct node { int row, col; struct node *down , *right; union v_next { datatype v; struc

zhangwanboy 1799
上一篇: 算法笔记-lc-面试题 01.09. 字符串轮转(中等)
下一篇: 大小根堆和java中双优先队列的应用
Hell_potato777
博客等级 码龄6年 47粉丝 106原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值