邻接表和逆邻接表的构建

一、邻接表

  1.为什么需要邻接表?

    答:当遇到的是稀疏图的情况下如果用邻接矩阵去存储的话,时间复杂度会是O(n^2),空间复杂度也会是O(n^2),其实这样是非常划不来的,因为你有很多空间没有用掉,所以就有了邻接表的存储方式

  2.邻接表是什么?

    答:可以把它当做一个链表来看待,他就是利用指向的形式寻找你的下一条边。

  3.邻接表的复杂度

     答:时间复杂度:O(n + e),空间复杂度O(e),e取决于边的数量  

  4.邻接表的作用

    答:可以较快速通过线性遍历知道某个顶点的入度和出度,这里我指的是有向图,当然无向图也可以求度

二、邻接表的构建

  给定一组数据

        // 0 1
        // 3 0
        // 2 0
        // 4 3
        // 4 2
        // 1 4
  
  开辟u,v,outf,next数组
  v代表顶点,u代表该组顶点到的另一个顶点,outf代表出度第一个顶点,next代表下一个顶点(这里请注意,next里面存的是顶点的编号,就是在v数组里面的第i条数据,这是一条链,不一定只有一个)
  实操开始
    1初始化 (注意u、v数组的初始下标为1,next,inf数组的初始下标为0)
      因为可能存在顶点为0的情况,所以我们令-1为空,首先outf是没有节点的所以应该初始化为空
    2.
      1.读入0-->1这条边
        outf【0】更新为1,表示在v和u的1号下标存了一组关于0的出边,具体是0-->n不知道,next[0]这里是更新为-1,表示还没有下一条边
      2.读入3-->0这条边
        outf【3】更新为2,表示在v和u的2号下标存了一组关于3的出边,next[3]更新为-1
      3.读入2-->0这条边
        outf【2】更新为3,表示在v和u的3号下标存了一组关于2的出边,next[2]更新为-1
      4.读入4-->3这条边
        outf【4】更新为4,表示在v和u的4号下标存了一组关于4的出边,next[4]更新为-1
      5.读入4-->2这条边
        outf【4】更新为5,表示在v和u的5号下标存了一组关于4的出边,next[5]更新为4
      6.读入1-->4这条边
        outf【1】更新为6,表示在v和u的6号下标存了一组关于1的出边,next[1]更新为-1
    处理后的图表为
      

 三、逆邻接表

  逆邻接表的思路和邻接表的思录一样,逆邻接表是用来求某个点的入度,而邻接表是求某个点的出度问题。

四、代码实现

复制代码
 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 int inf[110],outf[110];
 4 int inext[110],outnext[110];//in代表入度,out代表出度
 5 int v[110],u[110];
 6 int main()
 7 {
 8     for(int i = 1;i <= 100;i++)
 9         inf[i] = -1,outf[i] = -1;
10     int n,m;
11     cin >> n >> m;//n是顶点数,m是边数
12     int vi,ui;
13     for(int i = 1;i <= m;i++){
14         cin >> v[i] >> u[i];//vi-->ui是出度,ui-->vi是入度
15         outnext[i] = outf[v[i]];//outf建立的是邻接表
16         outf[v[i]] = i;
17         inext[i] = inf[u[i]];//inf建立的是逆邻接表
18         inf[u[i]] = i;
19     }
20     for(int i = 1;i <= n;i++){
21         int ink,outk;
22         ink = inf[i];
23         outk = outf[i];
24         if(ink != -1)
25             cout << u[ink] << "\nin:" << endl;
26         //以第i号节点为入度的边为
27         while(ink != -1){
28             cout << v[ink] << "-->" << u[ink] << endl;
29             ink = inext[ink];
30         }
31         if(outk != -1)
32             cout << "out:" << endl;
33         //以第i号节点为出度的边为
34         while(outk != -1){
35             cout << v[outk] << "-->" << u[outk] << endl;
36             outk = outnext[outk];
37         }
38         cout << "\n\n";
39     }
40     return 0;
41 }
复制代码
posted @   scannerkk  阅读(916)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示