链式前向星(详解)

链式前向星(详解)链式前向星 详解 转自 传送门我们首先来看一下什么是前向星 前向星是一种特殊的边集数组 我们把边集数组中的每一条边按照起点从小到大排序 如果起点相同就按照终点从小到大排序 并记录下以某个点为起点的所有边在数组中的起始位置和存储长度 那么前向星就构造好了 用 len i 来记录所有以 i 为起点的边在数组中的存储长度 用 head i 记录以 i 为边集在数组中的第一个存储位置 那么

链式前向星(详解)

转自:传送门

我们首先来看一下什么是前向星.

前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,

并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了.

用len[i]来记录所有以i为起点的边在数组中的存储长度.

用head[i]记录以i为边集在数组中的第一个存储位置.

我们输入边的顺序为:

1 2

2 3

3 4

1 3

4 1

1 5

4 5

那么排完序后就得到:

编号:     1      2      3      4      5      6      7

起点u:    1      1      1      2      3      4      4

终点v:    2      3      5      3      4      1      5

得到:

head[1] = 1    len[1] = 3

head[2] = 4    len[2] = 1

head[3] = 5    len[3] = 1

head[4] = 6    len[4] = 2

但是利用前向星会有排序操作,如果用快排时间至少为O(nlog(n))

如果用链式前向星,就可以避免排序.

我们建立边结构体为:

struct Edge

{

     int next;

     int to;

     int w;

};

其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值.

另外还有一个数组head[],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实

在以i为起点的所有边的最后输入的那个编号.

head[]数组一般初始化为-1,对于加边的add函数是这样的:

void add(int u,int v,int w) { edge[cnt].w = w; edge[cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt++; } 

初始化cnt = 0,这样,现在我们还是按照上面的图和输入来模拟一下:

edge[1].to = 3;     edge[1].next = -1;      head[2] = 1;

edge[2].to = 4;     edge[2],next = -1;      head[3] = 2;

edge[3].to = 3;     edge[3].next = 0;       head[1] = 3;

edge[4].to = 1;     edge[4].next = -1;      head[4] = 4;

edge[5].to = 5;     edge[5].next = 3;       head[1] = 5;

edge[6].to = 5;     edge[6].next = 4;       head[4] = 6;

很明显,head[i]保存的是以i为起点的所有边中编号最大的那个,而把这个当作顶点i的第一条起始边的位置.

这样在遍历时是倒着遍历的,也就是说与输入顺序是相反的,不过这样不影响结果的正确性.

比如以上图为例,以节点1为起点的边有3条,它们的编号分别是0,3,5   而head[1] = 5

我们在遍历以u节点为起始位置的所有边的时候是这样的:

for(int i=head[u];~i;i=edge[i].next)

那么就是说先遍历编号为5的边,也就是head[1],然后就是edge[5].next,也就是编号3的边,然后继续edge[3].next,也

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205525.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午5:49
下一篇 2026年3月19日 下午5:49


相关推荐

  • java实训总结_JAVA实训总结

    java实训总结_JAVA实训总结JAVA 实训总结 由会员分享 可在线阅读 更多相关 JAVA 实训总结 14 页珍藏版 请在人人文库网上搜索 1 JAVA 程序设计课程实训报告一 实训目的知识目标 1 了解图形用户界面的编程思路及方法 2 了解事件及事件处理机制 3 掌握常用的图形用户界面组件 4 掌握容器布局的设置方法及组件的添加方法 5 掌握常见事件类型及事件处理方法 能力目标 1 与客户沟通的基本能力 2 团队协作的基本能力 3 编程的良

    2026年3月20日
    2
  • js和java那个难_javascript与java哪个难?

    js和java那个难_javascript与java哪个难?javascript与java哪个难?答案是:JavaScript比Java更难。那么这是为什么?下面本篇文章就来给大家介绍一下,希望对大家有所帮助。原因:JavaScript有太多东西需要你自己去理解,这些东西里有很多要么Java已经给你做成范式了,你可以通过学习范式来理解;要么就是根本没有,无需理解。JavaScript需要在语言的基础上再整理一套方法论,这个过程会有不同流派。而Java基本上…

    2022年7月7日
    31
  • 深度相机种类_深度相机原理

    深度相机种类_深度相机原理本文首发于微信公众号:计算机视觉life。本文的深度相机制造商涉及:Microsoft、Intel、LeapMotion、Orbbec、图漾、OccipitalStructure、Stereolabs、DUO。文末附深度相机详细对比清单。MicrosoftKinect微软推出了两款Kinect,Kinect一代(Kinectv1)是基于结构光原理的深度相机,Kinect二代(Kine

    2025年6月23日
    6
  • C# ManualResetEvent

    C# ManualResetEvent原文链接http://dotnetpattern.com/threading-manualreseteventManualResetEvent和AutoResetEvent一样,是另外一种.NET线程同步技术。ManualResetEvent被用于在两个或多个线程间进行线程信号发送。多个线程可以通过调用ManualResetEvent对象的WaitOne方法进入等待或阻塞状态。当…

    2022年7月13日
    21
  • JAVA byte int 0xff 0xffffffff

    JAVA byte int 0xff 0xffffffffbyteb=0xff;这样无法通过编译。因为这时的0xff,是作为int类型的,其值为255,二进制记作0000000000000000 0000000011111111,另外,JAVA这里的二进制是用补码的。而byte的范围是-127~128,所以编译器无法通过。如果要想通过编译,应该如下:byteb=(byte)0xff;这时0xff,…

    2022年5月17日
    47
  • OutputStreamWriter的基本使用[通俗易懂]

    OutputStreamWriter的基本使用[通俗易懂]所有基于Writer类和Reader类的IO流都是字符流,字符流是高级流,必须基于字节流来构建OutputStreamWriter主要方法write(intn)write(Stringstr)write(Stringstr,intoffset,intlen)write(char[]cbuf)write(char[]cbuf,intoffset,intlen)举个栗子packagecom.wondream.myframework.app.basic

    2025年10月26日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号