1. 程式人生 > >圖的遍歷DFS和BFS

圖的遍歷DFS和BFS

鄰接矩陣的DFS和BFS遍歷

鄰接矩陣實現圖
#define Maxnum 100;
#define Maxnum 100
typedef struct ENode * Edge;
struct ENode
{
	int V1, V2;
	int weight;
};
typedef struct GNode * Graph;
struct GNode
{
	int Nv; // 頂點數
	int Ne; // 邊數
	int G[Maxnum][Maxnum];
};
Graph createGraph(int VertexNum) //建立一個無邊的圖
{
	Graph G = (Graph)
malloc(sizeof(struct GNode)); G->Nv = VertexNum; G->Ne = 0; for (int i = 0; i < G->Nv; i++) { for (int j = 0; j < G->Nv; j++) { G->G[i][j] = 0; } } return G; } void insertVertex(Graph G ,Edge E) { G->G[E->V1][E->V2] = E->weight; } int main() { int Nv; Graph G;
Edge E; scanf_s("%d", &Nv); //輸入頂點的個數 G = createGraph(Nv); //建立圖 scanf_s("%d", &G->Ne); //輸入圖的邊數 if (G->Ne != 0) { E = (Edge)malloc(sizeof(struct ENode)); for (int i = 0; i < G->Ne; i++) { scanf_s("%d%d%d", &E->V1, &E->V2, &E->weight); // 輸入一條邊 insertVertex
(G, E); // 插入邊 } } }

DFS的遍歷
與樹的先序遍歷類似

bool visited[Maxnum]; // 用來做標記,值為false表示節點未被訪問,true為已被訪問
void DFS(Graph G,int Vertex) 
{
	visited[Vertex] = true; // 訪問節點
	for(int i = 0; i<G->Nv;i++)
	{
		if(G[Vertex][i]!=0&&visited[i]==false)  
		{
			DFS(G,i);
		}	
	}
}
void ListDFS(Graph G) 
{
	for(int i=0;i<G->Nv;i++)
	{
		if(visited[i] == false)
		{
			DFS(G,i);
		}
	}
}

BFS遍歷 ,與層次遍歷類似;使用佇列實現

bool visited[Maxnum]; // 用來做標記,值為false表示節點未被訪問,true為已被訪問
void BFS(Graph G, int S)
{
	int V;
	Queue Q; // 佇列Q
	Q = creatQueue(Maxnum);// 初始化佇列;
	visited[S] = true // 訪問節點;
	AddQ(Q,S) // 入隊;
	while(IsEmptry(Q))
	{
		V = DelQ(Q);  // 出佇列
		for(int i = 0; i<G->Nv;i++)
		{
			if(G[V][i] !=0 &&visited[i] == false)
			{
				visited[i] = true ; //訪問
				AddQ(Q,i); //入隊
			}
		}
	}
}
void ListBFS(Graph G)
{
	for(int i; i<G->Nv;i++)
	{
		if(visited[i] == false)
		{
			BFS(G,i);
		}
	}
}

鄰接表的DFS與BFS的遍歷

鄰接表實現圖
#define Maxnum 100
typedef struct ENode * Edge;
struct ENode
{
	int V1, V2;
	int weight;
};
typedef struct AdjNode* Adj;
struct AdjNode
{
	int Adjv; // 下標
	int weight; // 權重
	Adj next; // 指向下一個;
};
typedef struct VNode
{
	Adj FirstEdge;
}AdjList[Maxnum];

typedef struct GNode * Graph;
struct GNode
{
	int Nv; // 頂點數
	int Ne; // 邊數
	AdjList G;
};
Graph CreateGraph(int VertexNum) //建立有VertexNum個頂點的圖
{
	Graph G = (Graph)malloc(sizeof(struct GNode));
	G->Nv = VertexNum;
	G->Ne = 0;

	for (int i = 0; i < G->Nv; i++)
	{
		G->G[i].FirstEdge = NULL;
	}
	return G;
}
void InsertEdge(Graph G, Edge E)
{
	Adj NewNode = (Adj)malloc(sizeof(struct AdjNode));
	NewNode->weight = E->weight;
	NewNode->Adjv = E->V2;
	NewNode->next = G->G[E->V1].FirstEdge;
	G->G[E->V1].FirstEdge = NewNode;
	//若為無向圖  將 V1 插入 V2
	NewNode = (Adj)malloc(sizeof(struct AdjNode));
	NewNode->Adjv = E->V1;
	NewNode->weight = E->weight;
	NewNode->next = G->G[E->V2].FirstEdge;
	G->G[E->V2].FirstEdge = NewNode;
}
void main()
{
	Graph G;
	Edge E;
	int Nv;
	scanf_s("%d", &Nv);
	G = CreateGraph(Nv);
	scanf_s("%d", &G->Ne);
	if (G->Ne != 0)
	{
		E = (Edge)malloc(sizeof(struct ENode));
		for (int i = 0; i < G->Ne; i++)
		{
			scanf_s("%d%d%d", &E->V1, &E->V2, &E->weight);
			InsertEdge(G, E);
		}
	}
}

DFS的遍歷

bool visited[Maxnum]; // 用來做標記,值為false表示節點未被訪問,true為已被訪問
void ListDFS(Graph G)
{
	for(int i = 0; i<G->Nv;i++)
	{
		if(visited[i])
		{
			DFS(G,i);
		}
	}
}
void DFS(Graph G , int Vertex)
{
	Adj W;
	visited[Vertex] = true;
	for(W = G->G[Vertex].FirstEdge ; W ; W=W->next)
	{
		if(!visited[W->Adjv])
		{
			DFS(G,W->Adjv);
		}
	}

BFS的遍歷

void BFS(Graph G,int i)
{
	linkQueue Q;
	Adj W;
	int V;
	Q = createQueue();
	AddQ(Q, i);
	visited[i] = true;
	printf("%d  ", i);
	while (!Emptry(Q))
	{
		V = DelQ(Q);
		for (W = G->G[V].FirstEdge; W ; W = W->next)
		{					
			if (!visited[W->Adjv])
			{
				visited[W->Adjv] = true;
				printf("%d  ", W->Adjv);
				AddQ(Q, W->Adjv);
			}
		}
	}
}
void ListBFS(Graph G)
{
	for (int i = 0; i < G->Nv; i++)
	{
		if (!visited[i])
		{
			BFS(G, i);
		}
	}
}