图的邻接表存储及图的遍历(DFS)

图的表示方式

  • 邻接矩阵:G[N][N],适合稠密图,占用空间大,O(N*N)。
  • 邻接表:存储稀疏有向图,避免空间浪费
  • 十字链表 :针对有向图,把邻接表和逆邻接表整合在一起,这样既容易找到以node为尾的弧,也能找到node为头的弧
  • 邻接多重表:针对无向图优化的存储结构

数组模拟邻接表存储图 及图的遍历

变量

	const int N=1E5+5,M=2*N;
	int h[N],e[M],ne[M],idx;
	bool st[N]; // 标记是否遍历过
	//初始化
	// 初始化邻接表和标记数组
    memset(h, -1, sizeof h);
    memset(st, false, sizeof st);
  • 变量解释
e[idx]:编号为idx的边,值为边指向的顶点,例如边(a->b). e[idx]=b;
ne[idx]:编号为idx的边的下一个边
h[idx]:a这个点所连接的第一个点的编号
idx:当前存储到的边的编号
  • 邻接表添加有向边(a->b):
void add(int a,int b){
	//存入a指向b的点
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
  • 举例说明:

请添加图片描述

图的遍历

在这里插入图片描述

  • 图的深度优先搜寻DFS
#include <bits/stdc++.h>
using namespace std;

// 全局变量
const int N = 1e5 + 10;
const int M = 2 * N;
int e[N], h[N], ne[N], idx=0; // 邻接表存图
bool st[N]; // 标记是否遍历过

// 添加一条边a->b
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void dfs(int u){
    if(st[u]) return;
    st[u]=true;		//标记已经被搜过
    cout<<u<<endl;
    for(int i=h[u];~i;i=ne[i]){//注释:~表示按位取反,-1取反=0,即:i!=-1
        int j=e[i];
        if(!st[j]) {
            dfs(j);	//只有没被搜过的才能继续搜索下去
        }
    }
}


int main() {
    // 初始化邻接表和标记数组
    memset(h, -1, sizeof h);
    memset(st, false, sizeof st);

    // 读入图的信息
   add(1 , 3);
   add(1,2);
   add(2,4);
   add (3,5);

    // 从任意一个未被遍历的节点开始 DFS 遍历
    for (int i = 1; i <= 5; i ++ )
        if (!st[i]) dfs(i);

    return 0;
}



  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
邻接表存储是一种常见的存储方式,其基本思想是将每个顶点的邻接点列表存储在一个数组中。具体来说,我们可以用一个数组来存储所有顶点,而对于每个顶点,我们用一个链表来存储邻接点列表。 下面是一个示例邻接表存储: ![邻接表示例](https://img-blog.csdn.net/20180607170352208?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p4LWJsb2c=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/80) 对应的邻接表为: ``` 0 -> 1 -> 2 -> 3 1 -> 0 -> 2 -> 4 2 -> 0 -> 1 -> 3 -> 4 3 -> 0 -> 2 4 -> 1 -> 2 ``` 深度优先遍历DFS)是一种常见的遍历算法,其基本思想是从某个顶点开始,沿着一条路径一直遍历到底,直到没有未访问的邻接点为止,然后回溯到上一个顶点,再选择另一条路径继续遍历,直到所有顶点都被访问过为止。 下面是的深度优先遍历的代码实现,其中graph为邻接表存储,visited为记录每个顶点是否被访问过的数组。 ``` void DFS(int v, vector<int> *graph, bool *visited) { visited[v] = true; cout << v << " "; for (int i = 0; i < graph[v].size(); i++) { int u = graph[v][i]; if (!visited[u]) { DFS(u, graph, visited); } } } ``` 其中v表示当前遍历到的顶点,graph表示邻接表存储,visited表示记录每个顶点是否被访问过的数组。在遍历过程中,我们首先将当前顶点标记为已访问,并输出其值。然后依次遍历邻接点,对于每个未访问过的邻接点,递归调用DFS函数进行遍历
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值