在这里对图的存储和遍历进行一个规范,为以后更复杂的数据结构学习打下基础

首先是邻接矩阵的形式,适合于存稠密图,如果是全连接图就再合适不过了

int a[maxn][maxn];

一个二维数组就可以搞定了,如果是bool值那么就是不带权值的

a[i][j]=w表示i->j这条边的权值为w,反之亦然

建图操作是很显然的

    for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
cin>>a[i][j];

接下来是一个DFS:

int vis[maxn];
void dfs(int dp,int x)
{
cout<<x<<" ";
for(int i=;i<=n;i++)
if(a[x][i]&&!vis[i])
{
vis[i]=;
dfs(dp+,i);
}
}

特别强调一下,我是先输出的结果,再进行的遍历,如果给定的图不是连通的,给了一片森林的话,一定要注意相应的细节

在这里的细节处理是给刚开始进入dfs的点打上标记,不要漏掉这里

然后是BFS,处理方法类似

int q[maxn];
void bfs(int x)
{
int h=,t=;
q[t]=x;
while(h!=t)
{
h=h%maxn+;
cout<<q[h]<<" ";
for(int i=;i<=n;i++)
if(a[q[h]][i]&&!vis[i])
{
vis[i]=;
t=t%maxn+;
q[t]=i;
}
}
}

接下来给出一个完整的例子:

 #include<iostream>
#include<cstring>
using namespace std;
const int maxn=;
int n;
int a[maxn][maxn];
int vis[maxn];
void dfs(int dp,int x)
{
cout<<x<<" ";
for(int i=;i<=n;i++)
if(a[x][i]&&!vis[i])
{
vis[i]=;
dfs(dp+,i);
}
}
int q[maxn];
void bfs(int x)
{
int h=,t=;
q[t]=x;
while(h!=t)
{
h=h%maxn+;
cout<<q[h]<<" ";
for(int i=;i<=n;i++)
if(a[q[h]][i]&&!vis[i])
{
vis[i]=;
t=t%maxn+;
q[t]=i;
}
}
}
int main()
{
cin>>n;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
cin>>a[i][j];
vis[]=;
dfs(,);
memset(vis,,sizeof(vis));
cout<<endl;
vis[]=;
bfs();
return ;
}
/*
0 1 1 0 0
1 0 0 1 1
1 0 0 0 0
0 1 0 0 0
0 1 0 0 0
*/

然后就是邻接链表了,邻接链表的存储形式是用的最多的

struct Edge
{
int t,w,next;
}e[maxm];
int g[maxn];
int tot=;

dalao们喜欢用vector改成邻接数组,我不是dalao,所以就先这样了(*^▽

意义还是很明显的,t代表着这条边的to节点,如果需要记录起始节点,就要存一个u了

由于是链表,next是必不可少的,存的是与此边共起点的下一条边的编号

然后就是g数组了,存的是由下标节点所引出的第一条边的编号

建图采用的是链表的头插法

void addedge(int a,int b,int c)
{
tot++;
e[tot].t=b;
e[tot].w=c;
e[tot].next=g[a];
g[a]=tot;
}

然后我们给出DFS和BFS的部分,这里原理是一模一样的,唯一需要注意的就是,数据结构变了,循环变量什么的要相应的调整

int vis[maxn];
void dfs(int dp,int x)
{
cout<<x<<" ";
for(int tmp=g[x];tmp;tmp=e[tmp].next)
if(!vis[e[tmp].t])
{
vis[e[tmp].t]=;
dfs(dp+,e[tmp].t);
}
}
int q[maxn];
void bfs(int x)
{
int h=,t=;
q[t]=x;
while(h!=t)
{
h=h%maxn+;
cout<<q[h]<<" ";
for(int tmp=g[q[h]];tmp;tmp=e[tmp].next)
if(!vis[e[tmp].t])
{
vis[e[tmp].t]=;
t=t%maxn+;
q[t]=e[tmp].t;
}
}
}

这里再补充一下刚才提到的森林的问题,由于我们是进入的时候就直接输出,所以第一个点一定要提前做好标记

由于是森林,每个点都要跑一边BFS或者DFS,那么在其他点的时候,进入之前判断vis,如果可行,打上vis之后再去跑,这样就没有任何问题了

最后给出邻接链表的完整实现:

 #include<iostream>
#include<cstring>
using namespace std;
const int maxn=;
const int maxm=;
int n,m;
struct Edge
{
int t,w,next;
}e[maxm];
int g[maxn];
int tot=;
void addedge(int a,int b,int c)
{
tot++;
e[tot].t=b;
e[tot].w=c;
e[tot].next=g[a];
g[a]=tot;
}
int vis[maxn];
void dfs(int dp,int x)
{
cout<<x<<" ";
for(int tmp=g[x];tmp;tmp=e[tmp].next)
if(!vis[e[tmp].t])
{
vis[e[tmp].t]=;
dfs(dp+,e[tmp].t);
}
}
int q[maxn];
void bfs(int x)
{
int h=,t=;
q[t]=x;
while(h!=t)
{
h=h%maxn+;
cout<<q[h]<<" ";
for(int tmp=g[q[h]];tmp;tmp=e[tmp].next)
if(!vis[e[tmp].t])
{
vis[e[tmp].t]=;
t=t%maxn+;
q[t]=e[tmp].t;
}
}
}
int main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
addedge(x,y,z);
addedge(y,x,z);
}
vis[]=;
dfs(,);
memset(vis,,sizeof(vis));
cout<<endl;
vis[]=;
bfs();
return ;
}

邻接链表是我最喜欢的一种存图的形式了

最后就是我觉得比较奇葩的邻接数组,是为了三级项目刻意实现的,当然如果把数组换成vector会更自然一些

这里直接给出完整实现,和邻接链表大同小异,唯一的区别就是不用存next,直接枚举数组下标就可以了

 #include<iostream>
#include<cstring>
using namespace std;
const int maxn=;
const int maxm=;
int n,m;
struct Edge
{
int t,w;
};
struct Graph
{
int cur;
Edge e[maxm];
}g[maxn];
int tot=;
void addedge(int a,int b,int c)
{
tot++;
Edge tmp;
tmp.t=b;
tmp.w=c;
g[a].cur++;
int t=g[a].cur;
g[a].e[t]=tmp;
}
int vis[maxn];
void dfs(int dp,int x)
{
cout<<x<<" ";
for(int tmp=;tmp<=g[x].cur;tmp++)
if(!vis[g[x].e[tmp].t])
{
vis[g[x].e[tmp].t]=;
dfs(dp+,g[x].e[tmp].t);
}
}
int q[maxn];
void bfs(int x)
{
int h=,t=;
q[t]=x;
while(h!=t)
{
h=h%maxn+;
cout<<q[h]<<" ";
for(int tmp=;tmp<=g[q[h]].cur;tmp++)
if(!vis[g[q[h]].e[tmp].t])
{
vis[g[q[h]].e[tmp].t]=;
t=t%maxn+;
q[t]=g[q[h]].e[tmp].t;
}
}
}
int main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
addedge(x,y,z);
addedge(y,x,z);
}
vis[]=;
dfs(,);
memset(vis,,sizeof(vis));
cout<<endl;
vis[]=;
bfs();
return ;
}

在每一种形式中,DFS和BFS先入栈和先入队的点是可能不一样的,但是结果都是正确的,在用之前一定要现在纸上画一画,避免输出顺序错误

数据结构&图论:图的更多相关文章

  1. python数据结构之图的实现

    python数据结构之图的实现,官方有一篇文章介绍,http://www.python.org/doc/essays/graphs.html 下面简要的介绍下: 比如有这么一张图: A -> B ...

  2. hdu 1233:还是畅通工程(数据结构,图,最小生成树,普里姆(Prim)算法)

    还是畅通工程 Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  3. 利用python+graphviz绘制数据结构关系图和指定目录下头文件包含关系图

    作为一名linux系统下的C语言开发,日常工作中经常遇到两个问题: 一是分析代码过程中,各种数据结构互相关联,只通过代码很难理清系统中所有结构体的整体架构,影响代码消化的效率; 二是多层头文件嵌套包含 ...

  4. python数据结构之图的实现方法

    python数据结构之图的实现方法 本文实例讲述了python数据结构之图的实现方法.分享给大家供大家参考.具体如下: 下面简要的介绍下: 比如有这么一张图:     A -> B     A ...

  5. python数据结构之图深度优先和广度优先实例详解

    本文实例讲述了python数据结构之图深度优先和广度优先用法.分享给大家供大家参考.具体如下: 首先有一个概念:回溯 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到 ...

  6. 数据结构之 图论---图的深度遍历( 输出dfs的先后遍历序列 )

    图的深度遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 请定一个无向图,顶点编号从0到n-1,用深度优先搜索(DFS),遍历并输出.遍历时,先遍历节点编 ...

  7. 数据结构&图论:K短路-可持久化可并堆

    本来A*就可以搞定的题,为了怕以后卡复杂度,找了个这么个方法 现阶段水平不够就不补充算法分析部分了 对于图G,建立一个以终点t为起点的最短路径构成的最短路径树 (就是反着跑一遍最短路,然后对于一个不为 ...

  8. 【PHP数据结构】图的应用:最短路径

    上篇文章的最小生成树有没有意犹未尽的感觉呀?不知道大家掌握得怎么样,是不是搞清楚了普里姆和克鲁斯卡尔这两种算法的原理了呢?面试的时候如果你写不出,至少得说出个大概来吧,当然,如果你是要考研的学生,那就 ...

  9. 数据结构之图 Part2 - 1

    邻接矩阵 网上很少有C# 写图的数据结构的例子,实际的项目中也从来没用过Array 这坨东西,随手写个,勿喷. namespace LH.GraphConsole { public struct Gr ...

随机推荐

  1. 十四:Using CGroups with YARN

        Cgroups可以控制linux 上应用程序的资源(内存.CPU)使用,yarn可以使用Cgroups来CPU使用.Cgroups的配置,在yarn-site.xml中设置: 1)启用Cgro ...

  2. Redis+Keepalived高可用方案详细分析

    背景 目前,Redis集群的官方方案还处在开发测试中,未集成到稳定版中.且目前官方开发中的Redis Cluster提供的功能尚不完善(可参考官方网站或http://www.redisdoc.com/ ...

  3. iOS- 给App添加内购& 验证购买iOS7新特性

    1.内购——应用内购买 我所说的内购——也可以说是应用内购买 大家都知道通过苹果应用程序商店有三种主要赚钱的方式: 1.直接收费(与国内大部分用户的消费习惯相悖,如果要收费,直接收高的,别收6块钱) ...

  4. Qt在VS(Visual Studio)中使用

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt在VS(Visual Studio)中使用     本文地址:https://www.te ...

  5. 【.Net】C# 反编译工具之dnSpy

    下载地址:https://github.com/0xd4d/dnSpy/releases无需安装,和 ILSPY同门,感觉比ILSPY还强大 直接把dll拖拽到程序集资源管理器里面就可以啦

  6. mac快速安装程序

    homebrew:mac套件管理 官网 :http://brew.sh/index_zh-cn.html macport: 官网:https://www.macports.org/

  7. 【bzoj2073】[POI2004]PRZ 状态压缩dp

    题目描述 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍过桥时只能分批 ...

  8. 新浪云部署java web程序 注意事项

    在新浪云新手指南里有部署java的示例,但是对一个新手来说难免会有一些地方犯错,折腾了好长时间才把自己的java web部署到了新浪云.这里主要写一些我遇到的问题与第一次使用新浪云的朋友分享一下. 首 ...

  9. poj 1469 COURSES (二分匹配)

    COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16877   Accepted: 6627 Descript ...

  10. Java的第一个程序-Hello, World !

    学了一个月的Java,现在总结一下,就算复习了. 一.安装Java环境 这个没啥好说的. 1. 官网下载JDK安装 2. 配置环境变量.注意的是:环境变量配置好以后,如果cmd中运行 java 命令没 ...