1. 程式人生 > >圖的深度優先遍歷(鄰接表,遞迴,非遞迴)

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

參考部落格:圖的深度優先遍歷(遞迴、非遞迴;鄰接表,鄰接矩陣)

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

樣例和執行結果與遞迴的一致