圖的深度優先遍歷(鄰接表,遞歸,非遞歸)


參考博客:圖的深度優先遍歷(遞歸、非遞歸;鄰接表,鄰接矩陣)

本代碼有個問題:就是結點是對應存儲下標的,要解決這個問題,可以增加一個定位函數(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;
}

樣例和運行結果與遞歸的一致


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM