【图】【邻接表】【DFS】求两个顶点间所有路径

语言:C语言

图的存储结构:链表

使用的数据结构:栈

图的遍历算法:DFS(深度优先算法)

我的图是这样滴

【图】【邻接表】【DFS】求两个顶点间所有路径_第1张图片

思路是这样滴:

因为从一个点到另一个点,每一步肯定是经过紧邻它的点,于是乎就要有一个for循环,从紧邻着它的第一个点开始一直到最后,每访问一个点,先判断该点在不在栈内,不在的话压栈,在的话说明已经访问过,再访问就成环了。然后判断它是不是终点。是终点就进入递归,因为判断是在递归函数的开始部分。综合考虑就是每一个for循环判断在栈内是否存在并且是否为终点。一但访问到终点,就输出栈内的所有顶点,就是从起点到终点的序列。然后将栈顶弹出(也就是终点)。返回上一个递归函数。看看终点前一个顶点还有没有其他的临界点可到终点。当该点的所有邻接结点都被访问过,再把该顶点弹出。

代码是这样滴:

#include
#define maxn 10

//栈的结构体
typedef struct
{
    int top;
    int num[maxn];
}Stack;

//邻接表的边结点
typedef struct
{
    int data;
    int quan;
    struct Arcnode* next;
}Arcnode;

//邻接表的头结点

typedef struct
{
    int data;
    Arcnode* first;
}Vnode;

//图的结构体

typedef struct
{
    int vexnum,arcnum;
    Vnode Vnode[maxn];
}ALGraph;

//图的创建

int CreateGraph(ALGraph *G)
{
    int i;

//先输入图的点数和边数
    printf("请输入图的点数和边数\n");
    scanf("%d%d",&G->vexnum,&G->arcnum);
    for(i=0;ivexnum;i++)
    {
        printf("请输入第%d个顶点的值\n",i+1);
        scanf("%d",&G->Vnode[i].data);
        G->Vnode[i].first=NULL;
    }

//在输入每条边所对应的两个结点,由于是无向图,所以插入链表时,两个顶点所对应的头结点的位置都要插入,采用头插法
    for(i=0;iarcnum;i++)
    {
        int j,k;
        Arcnode* p,*q;
        printf("请输入第%d条边的两个点\n",i+1);
        scanf("%d%d",&j,&k);
        p = (Arcnode*)malloc(sizeof(Arcnode));
        p->data = k;
        p->next = G->Vnode[j].first;
        G->Vnode[j].first = p;
        q = (Arcnode*)malloc(sizeof(Arcnode));
        q->data = j;
        q->next = G->Vnode[k].first;
        G->Vnode[k].first = q;
    }
}

//输出邻接表结构
void showALGraph(ALGraph *G)
{
    int i;
    Arcnode *t;
    for(i=0;ivexnum;i++)
    {
        t= G->Vnode[i].first;
        printf("%d",G->Vnode[i].data);
        while(t)
        {
            printf("->%d",t->data);
            t=t->next;
        }
        printf("\n");
    }
}

//初始化栈
Stack* init()
{
    Stack *s;
    s = (Stack*)malloc(sizeof(Stack));
    if(s==NULL)
    {
        printf("分配失败\n");
        return 0;
    }
    s->top=-1;
    return s;
}
void push(Stack *s,int v)
{
    if(s->top == maxn -1)
        return;
    s->num[++s->top] = v;
}
int pop(Stack *s)
{
    if(s->top == -1)
        return;
    else
        return s->num[s->top--];
}

//查看顶点是否在栈中
int check(Stack *s,int v)
{
    int i;
    for(i=0;i<=s->top;i++)
    {
        if(v==s->num[i])
            return 1;
    }
    return 0;
}

//输出栈内数据,也就是路径
void show(Stack* s)
{
    int m = s->top;
    int a = 0;
    while(a<=m)
    {
        printf("%d",s->num[a++]);
    }
    printf("\n");
}

//找到该结点紧邻的第一个顶点
int findfirst(ALGraph *G,int i)
{
    Arcnode *p;
    if(G->Vnode[i].first)
    {
        p=G->Vnode[i].first;
        //printf("第一个顶点是%d\n",p->data);
        return p->data;
    }
    else 
    {        
        return -1;
    }
}

//找到该结点紧邻的下一个顶点
int findnext(ALGraph *G,int i,int v)
{
    Arcnode *p,*q;
    if(G->Vnode[v].first)
    {
        p=G->Vnode[v].first;
        while(p->data!=i)
            p=p->next;
        q = p->next;
        if(q)
        {
            //printf("下一个顶点是%d\n",q->data);
            return q->data;
        }
        else
             return -1;
    }
    else 
        return -1;
}

//深度优先算法
void DFS(int B,int E,Stack* s,ALGraph *G){
    int i;
    push(s,B);
    if(E==B){
        show(s);
        pop(s);
        return;
    }
    for(i=findfirst(G,B);i!=-1;i=findnext(G,i,B)){
        //show(s);
        if(check(s,i)&&i!=E)
            continue;
        DFS(i,E,s,G);
    }
    pop(s);
}
int main(){
    ALGraph G;
    Stack *s;
    s = init();
    CreateGraph(&G);
    showALGraph(&G);
    DFS(0,2,s,&G);


}

以下是实验数据
/*
5 7
0
1
2
3
4
0 1
0 3
0 4
1 2
1 3
2 3
3 4
*/

输出的是0到2的所有路径

截图【图】【邻接表】【DFS】求两个顶点间所有路径_第2张图片

你可能感兴趣的:(上机练习,数据结构,图,DFS,所有路径)