图的遍历——DFS

来源:互联网 发布:万界淘宝商 编辑:程序博客网 时间:2024/06/06 12:24

最早接触到dfs是在小蝌蚪安家,就是dfs寻找最大连通块,当时对图还没有概念,也不知道这可以是个邻接矩阵,学数据结构之后,知道,一个图有两种存储结构——邻接矩阵和邻接表,遍历一个图也可以是dfs和bfs,dfs核心就是递归,bfs就是队列,然后递归的写法也可以用栈写成非递归的形式。

这里写图片描述

这个题中比较关键的首先是建图,题目点明是邻接表,其次是遍历是dfs,然后dfs要求是非递归过程

建立邻接表的过程,以样例1为例,如果是前插法,则邻接表的形式应该是
1 3 2
2 1
3 1
如果是尾插法的话,邻接表的形式应该是
1 2 3
2 1
2 3
然后根据深度优先遍历的结果(1,2,3)来看,应该是尾插法建图,本着举一反三,一题多解的原则,本题我们用三种方法来写,邻接表存储dfs非递归(合题意),邻接表存储dfs递归,邻接矩阵存储dfs递归。

邻接表dfs递归

#include<iostream>using namespace std;#include<string.h>typedef struct ArcNode{    int adjvex;    ArcNode *nextarc;    int info;}ArcNode;typedef struct VNode{    int data;    ArcNode *fistarc;}VNode;typedef struct ALGraph{    VNode vertices[500];    int vexnum,arcnum;}ALGraph;bool CreateUDG(ALGraph &G){    int i;    for(i=0;i<500;i++)    G.vertices[i].data=0;    for(i=1;i<=G.vexnum;i++)    {        G.vertices[i].data=i;        G.vertices[i].fistarc=NULL;    }    for(i=0;i<G.arcnum;i++)    {        int h,k;        cin>>h>>k;        ArcNode *p1;        p1=new ArcNode;        p1->adjvex=k;        p1->nextarc=NULL;        if(G.vertices[h].fistarc==NULL)        G.vertices[h].fistarc=p1;        else        {            ArcNode *temp;            temp=new ArcNode;            temp=G.vertices[h].fistarc;            while(temp->nextarc!=NULL)            temp=temp->nextarc;            temp->nextarc=p1;        }        ArcNode *p2;        p2=new ArcNode;        p2->adjvex=h;        p2->nextarc=NULL;        if(G.vertices[k].fistarc==NULL)        G.vertices[k].fistarc=p2;        else        {            ArcNode *temp;            temp=new ArcNode;            temp=G.vertices[k].fistarc;            while(temp->nextarc!=NULL)            temp=temp->nextarc;            temp->nextarc=p2;        }    }}bool visited[500];int num;void DFS_AL(ALGraph G,int v){    num++;    if(num!=G.vexnum)    cout<<v<<" ";    else    cout<<v<<endl;    visited[v]=true;    ArcNode *p;    p=new ArcNode;    p=G.vertices[v].fistarc;    while(p!=NULL)    {           int w;        w=p->adjvex;        if(!visited[w])            DFS_AL(G,w);        p=p->nextarc;    }    //这段代码好简洁}int main(){    int n,m;//n个顶点,m条边    while(scanf("%d%d",&n,&m)!=EOF&&n+m)    {        ALGraph G;        G.vexnum=n;        G.arcnum=m;        CreateUDG(G);        int f;        scanf("%d",&f);        memset(visited,0,sizeof(visited));        num=0;        DFS_AL(G,f);    }     return 0;}

邻接矩阵dfs递归

#include<iostream>using namespace std;#include<algorithm>#include<string.h>#define MAXINT 9999999;typedef struct AMGraph{    int arcs[100][100];    int vexs[100];    int arcnum,vexnum;}AMGraph;void CreateGraph(AMGraph &G){    int i,j;    for(i=0;i<100;i++)        G.vexs[i]=0;    for(i=0;i<100;i++)        for(j=0;j<100;j++)            G.arcs[i][j]=0;    for(i=1;i<=G.vexnum;i++)        G.vexs[i]=i;    for(i=1;i<=G.arcnum;i++)    {        int h,k;        scanf("%d%d",&h,&k);        G.arcs[h][k]=1;         G.arcs[k][h]=1;    }}bool visited[100];int num;void DFS_AMG(AMGraph G,int v){    num++;    visited[v]=true;    if(num!=G.vexnum)        cout<<v<<" ";    else        cout<<v<<endl;    int j;    for(j=1;j<=G.vexnum;j++)    {        //cout<<visited[j]<<endl;        //cout<<G.arcs[v][j]<<endl;        if((visited[j]==0)&&(G.arcs[v][j]==1))            DFS_AMG(G,j);    }}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF&&n+m)    {        AMGraph G;        G.vexnum=n;        G.arcnum=m;        CreateGraph(G);        int i;        for(i=0;i<100;i++)        visited[i]=false;        //memset(visited,0,sizeof(visited));        num=0;        int v;        scanf("%d",&v);        DFS_AMG(G,v);    }    return 0;}

这段代码开始的时候在我的编译器上怎么也运行不出来,我以为算法出了问题,结果是数组开大了,开始时500*500的,后来我换成了100*100的就可以了,这启示我们,二维数组这种东西,还真的是很有局限性…

原创粉丝点击