1. 程式人生 > >有向圖的強連通分支演算法kosaraju(C語言實現)

有向圖的強連通分支演算法kosaraju(C語言實現)

/* Kosaraju求強連通分量鄰接矩陣 */
#include "stdio.h"
#include "stdlib.h"
#define Vexnum 100
int map1[Vexnum][Vexnum]={0};
int nmap[Vexnum][Vexnum]={0};
int visited[Vexnum];

/*這部分是棧的定義和操作,可直接使用*/
struct StackSq{
int *stack1;
int top;
int MaxSize;
};
struct StackSq s;
void InitStack(struct StackSq *s)
{
s->MaxSize=100;/*置棧空間初始最大長度為100*/
s->stack1=(int *)malloc(10*sizeof(int));/*動態儲存空間分配*/
s->top=-1;/*置棧為空*/
}
//1
void Push(struct StackSq* S,int x)
{
//if(S->top==S->MaxSize-1)againMalloc(S);/*若棧空間用完則重新分配更大的儲存空間*/
S->top++;/*棧頂指標後移一個位置*/
S->stack1[S->top]=x;/*將新元素插入到棧頂*/
}
//2
int Pop(struct StackSq* S)
{
if(S->top==-1){
printf("棧空,無元素出棧!\n");
exit(1);
}
S->top--;
return S->stack1[S->top+1];
}
//3
int Peek(struct StackSq* s)
{
if(s->top==-1){
printf("棧空,無元素出棧!\n");
exit(1);
}
return s->stack1[s->top];
}
int EmptyStack(struct StackSq* S)
{
if(S->top==-1) return 1;
else return 0;
}

int N;  /*頂點數目*/
int DFS1(int  v) /* 深度遍歷有向圖G*/
{
    visited[v] = 1;
    for (int i = 1;i <= N;i++)
        if (!visited[i] && map1[v][i])
            DFS1( i );
    Push(&s,v);    /*這步很妙,時間順序*/
    return 0;
}
int DFS2( int v ) /* 深度遍歷有向圖G的逆圖*/
{
    visited[v] = 1;
    printf( "%d,", v );
    for (int i = 1;i <= N;i++)

        if ( !visited[i] && nmap[v][i] )
            DFS2( i );
    return 0;
}
int kosaraju()
{
    int i;
    while (!EmptyStack(&s))
        Pop(&s);
    for(i=1;i<=N;i++)
        visited[i]=0;
    for (int i = 1;i <= N;i++)
        if (!visited[i]) DFS1( i );
    int t = 0;
     for(i=1;i<=N;i++)

        visited[i]=0;
    while (!EmptyStack(&s))
    {
        int v = Peek(&s);
        Pop(&s);
        printf("{");
        if (!visited[v])
        {
            t++;
            DFS2( v );
        }
        printf("}");
    }
    return t;
}