图的深度优先遍历(邻接表,递归,非递归)

参考博客:图的深度优先遍历(递归、非递归;邻接表,邻接矩阵)

本代码有个问题:就是结点是对应存储下标的,要解决这个问题,可以增加一个定位函数(LocateVec),不修改也可以使代码简洁些

关于非连通图的bug已修改,就是增加了dfsTraverse函数循环遍历一遍结点:没访问过则再做一次dfs

 

样例一连通,样例二非连通

 

1.邻接表递归

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX 100

typedef struct EdgeNode// 边表结点
{
    int adjves;//存储顶点的下标
    struct EdgeNode* next;//连接下一个邻点
}EdgeNode;

typedef struct VertexNode//顶点表结点
{
    int ves;//顶点的值
    EdgeNode* firstedge;//相连的顶点的值
}VertexNode,AdjList[MAX];
//邻接表
typedef struct
{
    AdjList adjlist;
    int ves;//顶点
    int edge;//
    int book[MAX];//判断是否有被访问过
}MGraph;

void createMGraph(MGraph *G)
{
    int i;
    int start;
    int end;

    EdgeNode *e;

    printf("please input the ves and edge:\n");
    scanf("%d%d",&(G->ves),&(G->edge));
//初始化
    printf("please input the ves:\n");//此处设置顶点与存储下标相同且从零开始 

    for(i = 0; i < G->ves; i++)//输入顶点
    {
        scanf("%d",&(G->adjlist[i].ves));
        G->adjlist[i].firstedge = NULL;
    }
//创建邻接矩阵

    printf("please input the edges:\n");
    for(i = 0; i < G->edge; i++)
    {
        scanf("%d%d",&start,&end);

        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
        e->adjves = end;
        e->next = G->adjlist[start].firstedge;
        G->adjlist[start].firstedge = e;//类似于链表的前插


        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
        e->adjves = start;
        e->next = G->adjlist[end].firstedge;
        G->adjlist[end].firstedge = e;//类似于链表的前插
    }
}

void dfs(MGraph *G,int ves)
{
    EdgeNode *p;

    G->book[ves] = 1;//被访问过的结点置为1
    printf("%d ",G->adjlist[ves].ves);
    p = G->adjlist[ves].firstedge;//取顶点

    while(p)
    {
       if(G->book[p->adjves] == 0)//未被访问过
       {
           dfs(G,p->adjves);
       }
       p = p->next;
    }
}

void dfsTraverse(MGraph *G){
    int i;
    memset(G->book,0,sizeof(G->book));//清空标志位
    for(i = 0; i < G->ves; i++)
        if(!G->book[i])
            dfs(G, i);
} 

int main()
{
    MGraph G;
    createMGraph(&G);

    dfsTraverse(&G);
    return 0;
}
/*
输入样例_1:
5 6
0 1 2 3 4
0 1
1 2
2 3
2 0
3 4
0 4
输入样例_2:
5 4
0 1 2 3 4
0 1
0 2
1 2
3 4 
*/ 

 样例一结果:

样例二结果:

 

2.邻接表非递归

#include<iostream>
#include<stdlib.h>
#include<stack>
#include<stdio.h>
#include<string.h>

#define MAX 100

using namespace std;

typedef struct EdgeNode// 边表结点
{
    int adjves;//存储顶点的下标
    struct EdgeNode* next;//连接下一个邻点
}EdgeNode;

typedef struct VertexNode//顶点表结点
{
    int ves;//顶点的值
    EdgeNode* firstedge;//相连的顶点的值
}VertexNode,AdjList[MAX];
//邻接表
typedef struct
{
    AdjList adjlist;
    int ves;//顶点
    int edge;//
    int book[MAX];//判断是否有被访问过
}MGraph;

void createMGraph(MGraph *G)
{
    int i;
    int start;
    int end;

    EdgeNode *e;

    printf("please input the ves and edge:\n");//此处设置顶点与存储下标相同且从零开始 
    scanf("%d%d",&(G->ves),&(G->edge));
//初始化
    printf("please input the ves:\n");

    for(i = 0; i < G->ves; i++)//输入顶点
    {
        scanf("%d",&(G->adjlist[i].ves));
        G->adjlist[i].firstedge = NULL;
    }
//创建邻接矩阵

    printf("please input the edges:\n");
    for(i = 0; i < G->edge; i++)
    {
        scanf("%d%d",&start,&end);

        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
        e->adjves = end;
        e->next = G->adjlist[start].firstedge;
        G->adjlist[start].firstedge = e;//类似于链表的前插


        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
        e->adjves = start;
        e->next = G->adjlist[end].firstedge;
        G->adjlist[end].firstedge = e;//类似于链表的前插
    }
}

void dfs(MGraph *G,int i)
{
    stack <int>s;  
    EdgeNode *p;

    G->book[i]=1;  
    s.push(i);  
    printf("%d ", G->adjlist[i].ves);

    p = G->adjlist[i].firstedge; 
    while(!s.empty())  
    {  
        p = G->adjlist[s.top()].firstedge; 
        while(p)  
        {  
            if(G->book[p->adjves] == 0) 
            {                              
            G->book[p->adjves]=1;  
            printf("%d ",G->adjlist[p->adjves].ves);  

            s.push(p->adjves); 
            p = G->adjlist[p->adjves].firstedge; 
            }  
            else  
                p=p->next;  
        }
        if(p == NULL)
        {
            s.pop();  
         }
     }   
}

void dfsTraverse(MGraph *G){
    int i;
    memset(G->book,0,sizeof(G->book));//清空标志位
    for(i = 0; i < G->ves; i++)
        if(!G->book[i])
            dfs(G, i);
}

int main()
{
    MGraph G;
    createMGraph(&G);

    dfsTraverse(&G);
    return 0;
}

样例和运行结果与递归的一致

posted @ 2018-12-11 15:48  Johnny、  阅读(12171)  评论(0编辑  收藏  举报