DFS栈实现 C代码

这里代码写的比较随意,直接使用数组下标作为索引,而结点就是用0到n-1来表示。

类似于递归调用的思想(感觉就是把递归调用里面的调用栈用简单的栈数组来替代一下)。这里对于栈顶的元素,如果它为白色,则全局时间变量加一,且把它邻接链表里的白色节点全部入栈;而如果栈顶元素已经是灰色,就把它变成黑色,时间全局变量加一,并且出栈;如果栈顶元素是黑丝,直接出栈。(这里黑色是必须的,因为结点可能重复入栈)

时间计算:每个循环要么有黑色结点出栈,要么时间变量加一,所以运行时间为Θ(V+E),因为所有入栈的结点数不会超过邻接链表的总大小。

分析一下两个时间戳和父节点的赋值:

1) v.d是第一次探索这个节点的时间,即把它从白色变成灰色的时候对v.d进行赋值。

2) v.f是该结点的所有结点都被探索过后,即把它从灰色变为黑色的时候对v.f进行赋值。

3) v.pi在入栈的时候赋值。

 PS:网上搜了一下,发现有个方法是一个结点入栈就break,并对这个结点作处理。本质上没有太大区别,我这里使用较大的栈空间,而那种方法期望时间比较长。

#include <stdio.h>
#define N 100


typedef struct Vertex {
    int color;
    int pi;
    int d;
    int f;
    int index;//下标
}Vertex;

typedef struct Node{
    int index;//对应的结点的数组下标,相当于存储了该结点的指针
    struct Node *next;
}Node;

typedef struct List{
    Node *head;
}List;

int stack[N];
static int count = 0;
int time=0;
void DFS_V(List *Adj, Vertex *V, int n, int u);

void DFS(List *Adj,Vertex *V,int n){
    for (int i = 0; i < n; ++i){
        V[i].color = 0;
        V[i].pi = -1;
    }
    for (int i = 0; i < n; ++i){
        if (V[i].color == 0)
            DFS_V(Adj,V, n, i);
    }
}

void DFS_V(List *Adj, Vertex *V,int n, int u){
    stack[count++] = u;
    while (count){
        int v = stack[count - 1];
        if (V[v].color == 0){
            V[v].color = 1;
            ++time;
            V[v].d = time;
            Node *tmp = Adj[v].head;
            while (tmp){
                if (V[tmp->index].color == 0)
                {
                    stack[count++] = tmp->index;
                    V[tmp->index].pi = v;
                }
                tmp = tmp->next;
            }
        }
        else if (V[v].color==1){
            V[v].color = 2;
            ++time;
            V[v].f = time;
            --count;
        }
        else --count;
    }
}

void print(Vertex *v,int n){
    for (int i = 0; i <n; i++){
        printf("%d %d %d\n", v[i].d, v[i].f,v[i].pi);
    }
}
void print_a(List *adj, int n){
    for (int i = 0; i < n; ++i){
        Node *tmp = adj[i].head;
        while (tmp){
            printf("%d", tmp->index);
            tmp = tmp->next;
        }
        printf("\n");
    }
}


int main(){
    Vertex V[6];
    for (int i = 0; i < 6; ++i)
        V[i].index = i;
    List Adj[6] = { 0, 0, 0, 0, 0, 0 };
    
    /*while (1){
        int u, v;
        cin >> u >> v;
        if (u < 0)
            break;
        Node tmp = { v, Adj[u].head };
        Adj[u].head = &tmp;
    }
    */

    Node n1 = { 2, 0 }, n2 = { 1, &n1 }, n11 = {4,&n2};
    Adj[0].head = &n11;
    Node n3 = { 0, 0 }, n4 = { 4, &n3 }, n5 = { 3, &n4 };
    Adj[1].head = &n5;
    Node n6 = { 0, 0 }, n7 = { 5, &n6 };
    Adj[2].head = &n7;
    Node n8 = { 1, 0 };
    Adj[3].head = &n8;
    Node n9 = { 1, 0 };
    Adj[4].head = &n9;
    Node n10 = { 2, 0 };
    Adj[5].head = &n10;
    print_a(Adj, 6);

    DFS(Adj, V, 6);
    print(V, 6);
}

 

posted on 2015-04-15 15:23  Natsukashiii  阅读(1457)  评论(0编辑  收藏  举报

导航