图的建立(邻接矩阵)与其深度优先和广度优先遍历
生活随笔
收集整理的這篇文章主要介紹了
图的建立(邻接矩阵)与其深度优先和广度优先遍历
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
建立一個有向圖或無向圖,輸入其頂點數,邊數,并給出相應邊的權值,輸出該圖對應的鄰接矩陣,并用遞歸實現其深度優先遍歷和用隊列實現其廣度優先遍歷后的結果.
圖的遍歷?
從給定圖中任意指定的頂點(稱為初始點)出發,按照某種搜索方法沿著圖的邊訪問圖中所有頂點,使每個頂點僅被訪問一次,這個過程稱為圖的遍歷
圖的遍歷方法有兩種,一種叫深度優先遍歷(DFS),另一種叫廣度優先遍歷(BFS).
圖的鄰接矩陣表示
通常圖的表示有兩種方法:鄰接矩陣,鄰接表。
本文用鄰接矩陣實現,一是代碼量更少,二是代碼風格也更貼近C語言。但不論是圖的哪種實現方式,其基本的實現思想是不變的。
1:節點的信息,我們用一維數組a[n]來存儲,假設圖共有n個節點。
2:節點與節點間的關系,我們用二維數組b[n][n]存儲。
3:b[i][j]表示,從i到j有向連通,b[j][i]表示從j到i有向連通,而當i=j時(矩陣的對角線上的元素),b[i][j]沒有實際意思,在遍歷時,我可以用來存儲定節點是否訪問過。
深度優先遍歷(DFS)
圖的深度優先搜索(Depth First Search),和樹的先序遍歷比較類似。
它的思想:假設初始狀態是圖中所有頂點均未被訪問,則從某個頂點v出發,首先訪問該頂點,然后依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。 若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。
顯然,深度優先搜索是一個遞歸的過程
深度優先遍歷特點是,選定一個出發點后進行遍歷,能前進則前進,若不能前進,回退一步再前進,或再回退一步后繼續前進。依此重復,直到所有與選定點相通的所有頂點都被遍歷。
廣度優先遍歷(BFS)???????
廣度優先遍歷的過程是首先訪問初始點v,接著訪問頂點v的所有未被訪問過的鄰接點v1,v2,…,vt,然后再按照v1,v2,…,vt的次序訪問每一個頂點的所有未被訪問過的鄰接點,以此類推,直到圖中所有和初始點v有路徑相通的頂點都被訪問過為止。
在遍歷以鄰接表為存儲結構的圖時,需要使用一個隊列,
#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100 //最大定點頂點數
#define INFINITF 65535 //用 65535來表示無窮
#define MAX 100
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Boolean; //Boolean是布爾類型,其值是TRUE或FALSE
Boolean visited[MAX];
typedef struct{char vexs[MAXVEX]; //頂點表 int arc[MAXVEX][MAXVEX]; //鄰接矩陣,可看作邊表int numVertexes,numEdges; //圖中當前的頂點數 int GraphType; //圖的類型
}MGraph;
typedef struct{int data[MAXSIZE];int front; //頭指針 int rear; //尾指針,若隊列不空,指向隊列尾元素的下一個位置
}SqQueue;
//初始化一個空隊列
int InitQueue(SqQueue *Q)
{Q->front=0;Q->rear=0;return OK;
}
int QueueEmpty(SqQueue Q)
{if(Q.rear==Q.front)return TRUE;elsereturn FALSE;
}
//循環隊列入隊列操作
int EnQueue(SqQueue *Q,int e)
{if ((Q->rear+1)%MAXSIZE == Q->front); //隊列滿的判斷return ERROR;Q->data[Q->rear]=e; //將元素e賦值給隊尾Q->rear=(Q->rear+1)%MAXSIZE; //rear指針向后移一位置,若到最后則轉到數組頭部return OK; }
// 循環隊列出隊列操作
int DeQueue(SqQueue *Q,int *e)
{if (Q->front == Q->rear)return ERROR; //隊列空的判斷*e = Q->data[Q->front]; //將隊頭元素賦值給e Q->front=(Q->front+1)%MAXSIZE; //front指針向后移一位置return OK;
}
void CreateMGraph (MGraph *G)
{int i,j,k,w;printf("輸入頂點數和邊數:\n");scanf("%d %d",&G->numVertexes,&G->numEdges); //輸入頂點數和邊數fflush(stdin);for(i=0;i<G->numVertexes;i++){printf("第%d個頂點",i+1);scanf("%c",&G->vexs[i]);getchar (); }for(i=0;i<G->numVertexes;i++)for(j=0;j<G->numVertexes;j++)G->arc[i][j]=INFINITF ; //鄰接矩陣初始化 for(k=0;k<G->numEdges;k++){printf("輸入邊(vi,vj)上的上標i,下標j和權W:");scanf("%d %d %d",&i,&j,&w); //輸入邊(vi,vj)上的權WG->arc[i][j]=w;if(G->GraphType==0)G->arc[j][i]=G->arc[i][j]; //因為是無向圖,矩陣對稱 }
}//輸出鄰接矩陣
void output(MGraph *G)
{int i,j,count=0;for (i=0;i<G->numVertexes;i++)printf("\t%c",G->vexs[i]); printf("\n");for(i=0;i<G->numVertexes;i++){printf("%4c",G->vexs[i]);for(j=0;j<G->numVertexes;j++){printf("\t%d",G->arc[i][j]);count++;if(count%G->numVertexes==0)printf("\n");}}
}
//鄰接矩陣的深度優先遞歸算法
void DFS (MGraph G,int i)
{int j;visited[i]=TRUE;printf("%c ",G.vexs[i]); //打印頂點for(j=0;j<G.numVertexes;j++){if(G.arc[i][j]==1&&!visited[j])DFS(G,j); //對未訪問的鄰接頂點遞歸調用 }
}
//鄰接矩陣的深度遍歷操作
void DFSTraverse(MGraph G)
{int i;for(i=0;i<G.numVertexes;i++)visited[i]=FALSE; //初始化所有頂點狀態都是未訪問過狀態 for(i=0;i<G.numVertexes;i++)if(!visited[i]) //對未訪問過的頂點調用DFS,若是連通圖,只會執行一次 DFS(G,i);
}
void BFSTraverse(MGraph G)
{int i,j;SqQueue Q;for(i=0;i<G.numVertexes;i++)visited[i]=FALSE;InitQueue(&Q); //初始化一輔助用的隊列for(i=0;i<G.numVertexes;i++) //對每個頂點做循環 {if(!visited[i]) //若是未訪問過就處理 {visited[i]=TRUE; //設置當前頂點訪問過 printf("%c ",G.vexs[i]); //打印頂點EnQueue(&Q,i); //將此頂點入隊列 while(!QueueEmpty(Q)) //若當前隊列不為空 {DeQueue(&Q,&i); //將隊中元素出隊列,賦值給i for(j=0;j<G.numVertexes;j++){//判斷其他結點若與當前頂點存在且未訪問過 if(G.arc[i][j] == 1&& !visited[j]){visited[j]=TRUE; //將找到的此頂點標記為已訪問 printf("%c ",G.vexs[j]); //打印頂點 EnQueue(&Q,j); //將找到的此頂點入隊列 }}} } }
}
int main()
{MGraph G;int i,j;printf("輸入圖的類型(無向圖0/有向圖1):");scanf("%d",&G.GraphType); CreateMGraph (&G);printf("鄰接矩陣數據如下:\n");output(&G); printf("\n");printf("圖的深度優先遍歷如下:\n");DFSTraverse(G);printf("\n圖的廣度優先遍歷如下:\n");BFSTraverse(G);return 0;
}
總結
以上是生活随笔為你收集整理的图的建立(邻接矩阵)与其深度优先和广度优先遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 9 SystemUI之内
- 下一篇: 面试必问的性能测试流程,你真的会吗?