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

# define MAX 100

// 边节点
typedef struct enode {
    int adIndex; // 节点下标
    int weight; // 权,本代码中并未用到
    struct enode *next; // 下一个节点
}ENODE, *PE;

// 顶点
typedef struct vnode {
    char name;
    PE firstEdge; // 单链表
}VNODE, *PV, VLIST[MAX];

// 图(网)
typedef struct graph {
   VLIST vlist;
   int numVnodes, numEdges;
}GRAPH, *PG;

// 保存已遍历顶点
int visited[MAX];

void create(PG);
void traverse_dfs(GRAPH);
void dfs(GRAPH, int);


void dfs(GRAPH graph, int i)
{
    PE p;

    // 先标识并打印顶点
    printf("%c ", graph.vlist[i].name);
    visited[i] = 1;

    // 递归遍历与该顶点边有关的边节点
    p = graph.vlist[i].firstEdge;

    while (p) {
        if (!visited[p->adIndex]) {
            dfs(graph, p->adIndex);
        }
        // 犯了个错,下面这句加到上面括号中,会导致回退的时候进入死循环
        p = p->next;
    }
}

void traverse_dfs(GRAPH graph)
{
    int i;

    // 初始化所有顶点为未访问状态
    for (i=0; i<graph.numVnodes; i++) {
        visited[i] = 0;
    }

    // 开始遍历
    for (i=0; i<graph.numVnodes; i++) {
        if (!visited[i]) {
            dfs(graph, i);
        }
    }   
}

void create(PG g)
{
    int i, j, k;
    PE e;

    printf("请输入顶点数和边数:\n");
    scanf("%d %d", &g->numVnodes, &g->numEdges);

    getchar();
    // 根据顶点数创建顶点表(VLIST一维数组)
    printf("请一次性输入顶点的值: ");
    for (i=0; i<g->numVnodes; i++) {
        scanf("%c", &g->vlist[i].name);
        g->vlist[i].firstEdge = NULL;
    }


    // 边节点单链表填充(创建边)
    for (k=0; k<g->numEdges; k++) {
        printf("请输入第%d条边(vi, vj)对应下标:\n", k+1);
        scanf("%d %d", &i, &j);

        // 创建i的边表节点j(双向,因为是无向图)
        e = (PE)malloc(sizeof(ENODE));
        e->adIndex = j;
        e->next = g->vlist[i].firstEdge; // 头插法
        g->vlist[i].firstEdge = e;

        // 创建j的边表节点i(双向,因为是无向图)
        e = (PE)malloc(sizeof(ENODE));
        e->adIndex = i;
        e->next = g->vlist[j].firstEdge;
        g->vlist[j].firstEdge = e;
    }
    printf("create edge done.\n");
}

int main(void)
{
    GRAPH graph;
    create(&graph);
    printf("深度优先遍历结果: ");
    traverse_dfs(graph);
    putchar('\n');

    return 0;
}


output 说明: 和上一篇中图一样,但是深度遍历的结果不一样(填充边时使用头插法导致遍历切入点不一样导致)

[root@8be225462e66 c]# gcc dfs_adList.c && ./a.out
请输入顶点数和边数:
8 9
请一次性输入顶点的值: ABCDEFGH
请输入第1条边(vi, vj)对应下标:
0 1
请输入第2条边(vi, vj)对应下标:
1 2
请输入第3条边(vi, vj)对应下标:
2 5
请输入第4条边(vi, vj)对应下标:
1 4
请输入第5条边(vi, vj)对应下标:
0 4
请输入第6条边(vi, vj)对应下标:
0 3
请输入第7条边(vi, vj)对应下标:
3 6
请输入第8条边(vi, vj)对应下标:
6 4
请输入第9条边(vi, vj)对应下标:
6 7
create edge done.
深度优先遍历结果: A D G H E B C F
[root@8be225462e66 c]#