图的存储-链式前向星

链式前向星

链式前向星是民间OI选手发明的数据结构。用另一个词解释它就是:用数组模拟的邻接链表。最核心的思想就是用数组模拟链表。

(1)前向星

前向星就是边的集合。一个图,只要将它的所有边存储起来,就能知道它的所有信息。但是前向星对于边的存储做了一些排序。

假设有如下图: 输入a->b,有一条a指向b的边。

复制代码
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

如果用前向星存图,至少需要三个数组:边的数组,起点开始位置的数组,起点终点位置的数组。并且还涉及边的排序,比较麻烦。

(2)链式前向星

链式前向星摒弃了排序,采用链表思想存储同一个起点的边,又为了避免链表结构的臃肿,利用数组模拟链表。

同样需要三个数组:边的数组edge、起点的第一条边位置的数组head、每条边相同起点的下一条边位置的数组next

  • edge【i】存储的是第i条边;

  • head【i】表示以节点序号i为起点的第一条边存储位置;

  • next【i】表示第i条边的下一条边,要求下一条边与这条边同起点。

注意:

上述声明涉及两种序号概念------节点的序号和边的序号!边的序号由输入顺序给定,节点的序号用来区分节点。

极端优化:由于head【i】已经知道边的起点,所以edge【i】也没必要存边的起点,直接存边的终点。这样,假设无权图输入都是整数,我们只需要三个一维整数数组就能存储整个图!

对于有权图的情况,edge【i】需要额外存储边的权值。参考博客

(3)应用

输入每条边,然后按起点顺序输出每条边。

java 复制代码
public class Main {
    public static void main(String[] args) throws InterruptedException{
        Scanner cin = new Scanner(System.in);
        int N = cin.nextInt(); //N个顶点
        int M = cin.nextInt(); //M条边
        int[] edge = new int[M];
        int[] head = new int[N+1]; //节点编号从1开始
        int[] next = new int[M];
        Arrays.fill(head, -1); //-1作为链表的结束标志
        // 输入
        for(int i=0; i<M; ++i){
            // 输入一条边 a->b
            cin.nextLine();
            int a = cin.nextInt();
            int b = cin.nextInt();
            // 存入三个数组中
            edge[i] = b;
            next[i] = head[a];
            head[a] = i;
        }
        // 输出:遍历每个起点的边
        for(int i=1; i<=N; ++i){
            int start = head[i];
            while(start!=-1){
                System.out.println(i+"->"+edge[start]);
                start = next[start];
            }
        }
    }
}

输入:首行表示5个节点,7条边,节点编号从1开始。

复制代码
5 7
1 2
2 3
3 4
1 3
4 1
1 5
4 5

输出:按节点顺序输出所有边。

复制代码
1->5
1->3
1->2
2->3
3->4
4->5
4->1

可以看到,链表其实是从后往前建的,所以head数组要初始化为-1。

相关推荐
空白到白18 小时前
决策树-面试题
算法·决策树·机器学习
flashlight_hi18 小时前
LeetCode 分类刷题:2563. 统计公平数对的数目
python·算法·leetcode
前端世界18 小时前
HarmonyOS 数据处理性能优化:算法 + 异步 + 分布式实战
算法·性能优化·harmonyos
楼田莉子18 小时前
C++算法专题学习:栈相关的算法
开发语言·c++·算法·leetcode
kyle~19 小时前
排序---冒泡排序(Bubble Sort)
c语言·c++·算法
l1t19 小时前
我改写的二分法XML转CSV文件程序速度追上了张泽鹏先生的
xml·c语言·人工智能·算法·expat
一碗白开水一19 小时前
【论文阅读】Far3D: Expanding the Horizon for Surround-view 3D Object Detection
论文阅读·人工智能·深度学习·算法·目标检测·计算机视觉·3d
轮到我狗叫了19 小时前
力扣.1054距离相等的条形码力扣767.重构字符串力扣47.全排列II力扣980.不同路径III力扣509.斐波那契数列(记忆化搜索)
java·算法·leetcode
久菜盒子工作室19 小时前
量化金融|基于算法和模型的预测研究综述
算法·金融
CoovallyAIHub20 小时前
SBP-YOLO:面向嵌入式悬架的轻量实时模型,实现减速带与坑洼高精度检测
深度学习·算法·计算机视觉