1. 程式人生 > >無向圖的深度優先遍歷和廣度優先遍歷(鄰接連結串列)

無向圖的深度優先遍歷和廣度優先遍歷(鄰接連結串列)

我選的是鄰接連結串列,建立如下圖所示的圖:

我把它畫出來,圖是這樣子的:

對於深度優先遍歷:是從一個頂點v出發,一步一步地向前推進,當找不到未訪問過的頂點時,也是一步一步地回退。其過程類似於用棧求解迷宮問題的搜尋方式。

比如上面這個圖:我從4這個頂點開始遍歷,它先訪問它第一個鄰接點1,然後1訪問它的第一個鄰接點4,發現4已經訪問過了,然後訪問第二個鄰接點2,2訪問第一個鄰接點1,發現1已經被訪問過,回退到1,1訪問第三個鄰接點3,3的第一個第二個鄰接點已經被訪問,我們就不訪問它,最後回退到4,4訪問第二個鄰接點3,可是3已經被訪問,我們就不訪問了。

對於廣度優先遍歷:是從一個頂點v出發,先訪問其所有相鄰的未訪問過的頂點。相當於以初始點為中心,一層一層地向外推進的。其過程類似於用佇列求解迷宮問題的搜尋方式。

比如上面這個圖:我從4這個頂點開始訪問,先訪問1,接著訪問3,然後訪問和3相鄰的頂點4、1,4、1都被訪問過,回退訪問1相鄰的未訪問的頂點1。

我是這樣理解的,讀者可以根據自己的測試資料來理解,歡迎和我交流。

完整程式碼:

    #include <stdio.h>  
    #include <conio.h>  
    #include <malloc.h>  
    #define MAX_NUM 20  
    typedef struct ArcNode {  
        int adjvex;  
        struct ArcNode *nextarc;  
    }ArcNode;  
    typedef int VertexType;  
    typedef struct VNode {  
        VertexType data;  
        ArcNode *firstarc;  
    }VNode,AdjList[MAX_NUM];  
    void createDgraph(AdjList &g,int n){  
        ArcNode *p,*q;  
        int i,j;  
        for (i=1;i<=n;i++)  
        {  
            g[i].data=i;  
            g[i].firstarc=NULL;  
        }  
        printf("\nEdgei->j:");  
        scanf("%d%d",&i,&j);  
        while (i!=-1)  
        {  
            p=(ArcNode *)malloc(sizeof(ArcNode));  
			q=(ArcNode *)malloc(sizeof(ArcNode));  
            p->adjvex=j;  
            p->nextarc=g[i].firstarc;  
            g[i].firstarc=p;  
			 q->adjvex=i;  
            q->nextarc=g[j].firstarc;  
            g[j].firstarc=q;  
            printf("\nEdge i->j:");  
            scanf("%d%d",&i,&j);  
        }  
    }  
	int visited[MAX_NUM]={0};
	void DFS(AdjList G,int v){
		ArcNode *p;
		visited[v]=1;
		printf("%d ",v);
		p=G[v].firstarc;
		while(p!=NULL){
			if(visited[p->adjvex]==0){//若w=p->adjvex 頂點未訪問,遞迴訪問它
				DFS(G,p->adjvex);
			}
			p=p->nextarc;//p指向頂點v的下一個鄰接點
		}
	}

	void BFS(AdjList G,int v){
		ArcNode *p;
		int Qu[20],front,rear;//定義迴圈佇列
		int visited[20]={0};
		int w,i;
		front=rear=0;//初始化佇列
		printf("%d ",v);
		visited[v]=1;
		rear=(rear+1)%20;
		Qu[rear]=v;//v進隊
		while(front!=rear){
			front=(front+1)%20;
			w=Qu[front];//出隊並賦給w
			p=G[w].firstarc;//找與頂點w鄰接的第一個頂點
			while(p){
				if(visited[p->adjvex]==0){//弱當前頂點未被訪問
					printf("%d ",p->adjvex);//訪問鄰接頂點
					visited[p->adjvex]=1;
					rear=(rear+1)%20;//該頂點進隊
					Qu[rear]=p->adjvex;
				}
				p=p->nextarc;
			}
		}
	}
    void printDgraph(AdjList g,int n){  
        ArcNode *p;  
        int i;  
        for (i=1;i<=n;i++)  
        {  
            printf("\n%d: ",g[i].data);  
            p=g[i].firstarc;  
            while (p)  
            {  
                printf("->%d",p->adjvex);  
                p=p->nextarc;  
            }  
        }  
    }  
    int main()  
    {  
        AdjList g;  
        int num;  
        printf("Input Number of Vertex:");  
        scanf("%d",&num);  
        createDgraph(g,num);  
        printDgraph(g,num);  
        printf("\n");  
		printf("深度優先:");
		DFS(g,num);
		printf("\n");
		printf("廣度優先:");
		BFS(g,num);
		printf("\n");
        return 0;  
    }  


對於圖的管