#include <stdio.h> #include <malloc.h> #define MAXV 100//最大頂點個數 int visited[MAXV];//全局數組 typedef int InfoType; typedef struct { int edges[MAXV][MAXV];//鄰接矩陣 int vexnum,arcnum; //頂點數,弧數 } MGraph;//圖的鄰接矩陣類型 typedef struct ANode { int adjvex; //該弧的終點位置 struct ANode *nextarc; //指向下一條弧的指針 InfoType info; //該弧的相關信息,這里用於存放權值 n } ArcNode;//弧的結點結構類型 typedef struct Vnode { //int data; //頂點信息 ArcNode *firstarc;//指向第一條弧 } VNode;//鄰接表頭結點的類型 typedef struct { VNode adjlist[MAXV];//鄰接表 int n,e;//圖中頂點數n和邊數e } ALGraph;//圖的鄰接表類型 void init(MGraph &g);//初始化鄰接矩陣 void MatToList(MGraph,ALGraph *&);//將鄰接矩陣g轉換成鄰接表G void DispAdj(ALGraph *);//輸出鄰接表G void DFS(ALGraph *G,int v);//深搜 void BFS(ALGraph *G,int v);//廣搜 void main() { MGraph g; g.vexnum=11;g.arcnum=13; init(g);//初始化鄰接矩陣 ALGraph *G=(ALGraph *)malloc(sizeof(ALGraph)); MatToList(g,G);//將鄰接矩陣g轉換成鄰接表G DispAdj(G);//輸出鄰接表G for (int i=0;i<g.vexnum;i++) visited[i]=0; printf("深度優先生成樹:"); DFS(G,3);//從頂點3開始深度搜索 printf("\n"); ////// for (i=0;i<g.vexnum;i++) visited[i]=0; printf("廣度優先生成樹:"); BFS(G,3);//從頂點3開始廣度搜索 } void DFS(ALGraph *G,int v)//從頂點v開始深度搜索 { visited[v]=1;//置已訪問標記 ArcNode *p=G->adjlist[v].firstarc;//p指向頂點v的第一條弧的弧頭結點 while (p!=NULL) { if (visited[p->adjvex]==0)//若p->adjvex頂點未訪問,遞歸訪問它 { printf("<%d,%d> ",v,p->adjvex);//輸出生成樹的一條邊 DFS(G,p->adjvex);//遞歸函數 } p=p->nextarc;//p指向頂點v的下一條弧的弧頭結點 } } void BFS(ALGraph *G,int v) { int queue[MAXV],front=0,rear=0; //定義循環隊列並初始化 int visited[MAXV]; //定義存放結點的訪問標志的數組 for (int i=0;i<G->n;i++) visited[i]=0; //訪問標志數組初始化 visited[v]=1; //置已訪問標記 queue[rear]=v;//已訪問過的頂點v進隊 rear=(rear+1)%MAXV; while (front!=rear)//若隊列不空時循環 { int w=queue[front];//出隊並賦給w front=(front+1)%MAXV; ArcNode *p=G->adjlist[w].firstarc; //找與頂點w鄰接的第一個頂點 while (p!=NULL) { if (visited[p->adjvex]==0) //若當前鄰接頂點未被訪問 { printf("<%d,%d> ",w,p->adjvex);//輸出生成樹的一條邊 visited[p->adjvex]=1;//置該頂點已被訪問的標志 queue[rear]=p->adjvex;//該頂點p的終點進隊 rear=(rear+1)%MAXV; } p=p->nextarc;//找下一個鄰接頂點 } } printf("\n"); } void init(MGraph &g) { int i,j; int A[MAXV][11]; for (i=0;i<g.vexnum;i++) for (j=0;j<g.vexnum;j++) A[i][j]=0; A[0][3]=1;A[0][2]=1;A[0][1]=1; A[1][5]=1;A[1][4]=1; A[2][6]=1;A[2][5]=1;A[2][3]=1; A[3][7]=1; A[6][9]=1;A[6][8]=1;A[6][7]=1; A[7][10]=1; for (i=0;i<g.vexnum;i++) for (j=0;j<g.vexnum;j++) A[j][i]=A[i][j];//無向圖雙向路徑對稱 for (i=0;i<g.vexnum;i++) for (j=0;j<g.vexnum;j++) g.edges[i][j]=A[i][j]; } void MatToList(MGraph g,ALGraph *&G)//將鄰接矩陣g轉換成鄰接表G { int i,j; G=(ALGraph *)malloc(sizeof(ALGraph)); for (i=0;i<g.vexnum;i++)//表頭節點的指針域置初值 G->adjlist[i].firstarc=NULL; for (i=0;i<g.vexnum;i++)//對於鄰接矩陣中每個元素 for (j=g.vexnum-1;j>=0;j--) if (g.edges[i][j]!=0)//鄰接矩陣的當前元素不為0---頂點i到j可以走通 { ArcNode *p=(ArcNode *)malloc(sizeof(ArcNode));//創建一個新的弧節點 p->adjvex=j;//弧節點的指向的終點位置 p->info=g.edges[i][j];//弧節點的長度 p->nextarc=G->adjlist[i].firstarc;//將*p鏈到表頭后 G->adjlist[i].firstarc=p;//更新表頭指針//G->adjlist[i]---表頭:頂點i連通到可連通的點 } G->n=g.vexnum;//鄰接表G的節點數 G->e=g.arcnum;//弧數 } void DispAdj(ALGraph *G)//輸出鄰接表G { printf("圖G的鄰接表:\n"); for (int i=0;i<G->n;i++)// { ArcNode *p=G->adjlist[i].firstarc; if (p!=NULL) printf("%3d: ",i);//輸出表頭元素 while (p!=NULL) { printf("%3d",p->adjvex);//輸出表頭后鏈接的元素 p=p->nextarc; } printf("\n"); } } /* 圖G的鄰接表: 0: 1 2 3 1: 0 4 5 2: 0 3 5 6 3: 0 2 7 4: 1 5: 1 2 6: 2 7 8 9 7: 3 6 10 8: 6 9: 6 10: 7 深度優先生成樹:<3,0> <0,1> <1,4> <1,5> <5,2> <2,6> <6,7> <7,10> <6,8> <6,9> 廣度優先生成樹:<3,0> <3,2> <3,7> <0,1> <2,5> <2,6> <7,10> <1,4> <6,8> <6,9> */