列出圖的連通集

  • 題目來源:

浙江大學在慕課網上開設的《數據結構》課,陳越老師、何欽銘老師主講,課後做業的一道題。數組

  • 題目描述:

  • 思路:

很是基礎的一道題,主要考察圖的DFS遍歷和BFS遍歷,最後注意輸出的格式就能夠了。數據結構

  • C語言實現:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MaxVerterNum 100  //最大定點數設爲100
#define INFINITY 65535  //無窮設爲雙字節無符號整數的最大值65535

typedef int WeightType;  //邊的權值設爲int類型
typedef char DataType;  //頂點存儲的數據類型設置爲字符類型
typedef int Vertex;  //用頂點下標表示頂點,爲整型

bool Visited[MaxVerterNum];

struct QNode
{
	int* Data;  //存儲元素的數組
	int Front;  //隊列的頭指針
	int Rear;  //隊列的尾指針
	int MaxSize;  //隊列的最大容量
};

//建立一個隊列
struct QNode* CreateQueue(int MaxSize)
{
	struct QNode* Q = (struct QNode*)malloc(sizeof(struct QNode));
	Q->Data = (int *)malloc(MaxSize * sizeof(int));
	Q->Front = Q->Rear = 0;
	Q->MaxSize = MaxSize;
	return Q;
}

bool IsFull(struct QNode* Q)
{
	return ((Q->Rear + 1) % Q->MaxSize) == Q->Front;
}

//在隊列尾插入一個元素
//參數 struct QNode* Q 要操做的隊列
//     int x  待插入的元素
bool AddQ(struct QNode* Q, int x)
{
	if (IsFull(Q))  //判斷隊列是否爲空
	{
		printf("隊列滿,不能再插入元素\n");
		return false;
	}
	else
	{
		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
		Q->Data[Q->Rear] = x;
		return true;
	}
}

//判斷隊列是否爲空
bool IsEmpty(struct QNode* Q)
{
	return (Q->Front == Q->Rear);
}
//在隊列頭部刪除一個元素
int DeleteQ(struct QNode* Q)
{
	if (IsEmpty(Q))
	{
		printf("隊列爲空\n");
		return false;
	}
	else
	{
		Q->Front = (Q->Front + 1) % Q->MaxSize;
		return Q->Data[Q->Front];
	}

}

struct GNode 
{
	int Nv;  //頂點數
	int Ne;  //邊數
	WeightType G[MaxVerterNum][MaxVerterNum];  //鄰接矩陣
	DataType Data[MaxVerterNum][MaxVerterNum];  //存頂點的數據
	/*若是頂點無數據,此時Data[]能夠不出現*/
};
//描述邊的類型
struct ENode
{
	Vertex V1, V2;  //有向邊<V1,V2>
	WeightType Weight;  //權重
};
//做用:初始化一個有VertexNum個頂點但沒有邊的圖
struct GNode* CreateGraph(int VertexNum)
{
	Vertex V, W;
	struct GNode* Graph;
	Graph = (struct GNode*)malloc(sizeof(struct GNode));  //創建圖
	Graph->Nv = VertexNum;
	Graph->Ne = 0;

	//初始化鄰接矩陣
	for (V = 0;V < Graph->Nv;V++)
	{
		for (W = 0;W < Graph->Nv;W++)
		{
			Graph->G[V][W] = INFINITY;
		}
	}
	return Graph;
}

//做用:在圖中插入邊
void InsertEdge(struct GNode* Graph,struct ENode* E)
{
	////插入邊<V1,V2>
	//Graph->G[E->V1][E->V2] = E->Weight;
	////如果無向圖,還須要插入<V2,V1>
	//Graph->G[E->V2][E->V1] = E->Weight;

	//插入邊<V1,V2>
	Graph->G[E->V1][E->V2] = 1;
	//如果無向圖,還須要插入<V2,V1>
	Graph->G[E->V2][E->V1] = 1;
}
//做用:構建一個圖,供主函數調用
struct GNode* BulidGraph()
{
	Vertex V;
	int NV;
	struct ENode* E;
	struct GNode* Graph;
	scanf("%d",&NV);  //讀入頂點個數
	Graph = CreateGraph(NV);
	scanf("%d",&(Graph->Ne));  //讀入邊數

	if (Graph->Ne != 0)
	{
		E = (struct ENode*)malloc(sizeof(struct ENode));
		for (int i = 0;i < Graph->Ne;i++)
		{
			////若是權重不是整型,Weight的讀入格式要改
			//scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
			scanf("%d %d", &E->V1, &E->V2);
			InsertEdge(Graph,E);
		}
	}

	////若是頂點有數據的話,讀入數據
	//for (V = 0;V < Graph->Nv;V++)
	//{
	//	scanf("%c",&(Graph->Data[V]));
	//}

	return Graph;
}

void Visit(Vertex V)
{
	printf(" %d",V);
}
//這個DFS是我本身寫的
//void DFS(struct GNode* Graph,Vertex V,void(* Visit)(Vertex))
//{
//	Vertex W;
//	Visit(V);
//	Visited[V] = true;
//
//	for (W = V + 1; W < Graph->Nv; W++)
//	{
//		if (Graph->G[V][W] == 1)
//		{
//			if (!Visited[W])
//			{
//				DFS(Graph, W, Visit);
//			}
//		}
//	}
//}

void DFS(struct GNode* Graph, Vertex V, void(*Visit)(Vertex))
{
	Vertex j;
	Visited[V] = true;
	Visit(V);

	for (j = 0;j < Graph->Nv;j++)
	{
		if (Graph->G[V][j] == 1 && !Visited[j])
		{
			DFS(Graph,j,Visit);
		}
	}
}

void DFSTraverser(struct GNode* Graph)
{
	int i = 0;
	//初始化全部頂點都是未訪問的狀態
	for (i = 0;i < Graph->Nv;i++)
	{
		Visited[i] = false;
	}

	for (i=0;i < Graph->Nv;i++)
	{
		if (!Visited[i])
		{
			printf("{");
			DFS(Graph,i,Visit);    
			printf(" }\n");
		}
	}
}

bool IsEdge(struct GNode* Graph,Vertex V,Vertex W)
{
	return Graph->G[V][W] < INFINITY ? true : false;
}

void BFS(struct GNode* Graph, Vertex S, void(*Visit)(Vertex))
{
	struct QNode* Q;
	Vertex V, W;
	Q = CreateQueue(20);

	Visited[S] = true;
	Visit(S);
	AddQ(Q,S);

	while (!IsEmpty(Q))
	{
		V = DeleteQ(Q);
		for (W = 0;W < Graph->Nv;W++)
		{
			//若W是V的鄰接點 而且 沒有訪問過
			if (!Visited[W] && IsEdge(Graph,V,W))
			{
				Visit(W);  //訪問節點
				Visited[W] = true;
				AddQ(Q,W);
			}
		}
	}
}
void BFSTraverser(struct GNode* Graph)
{
	int i = 0;
	//初始化全部頂點都是未訪問的狀態
	for (i = 0; i < Graph->Nv; i++)
	{
		Visited[i] = false;
	}

	for (i = 0; i < Graph->Nv; i++)
	{
		if (!Visited[i])
		{
			printf("{");
			BFS(Graph, i, Visit);
			printf(" }\n");
		}
	}
}

int main()
{
	struct GNode* Graph = BulidGraph();
	// printf("圖創建完畢.\n");
	DFSTraverser(Graph);
	BFSTraverser(Graph);
	// system("pause");
	return 0;
}
相關文章
相關標籤/搜索