进入图的学习,发现难度直线上升,哈哈,全部满分
其实,在这个题里,邻接矩阵更好,但我们是来学习数据结构的,便突发奇想都来实现一遍。
以下是我的两种形式
给定一个有 n 个顶点和 m 条边的无向图,请用深度优先遍历(DFS)和广度优先遍历(BFS)分别列出其所有的连通集。假设顶点从 0 到 n−1 编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
输入第 1 行给出 2 个整数 n (0<n≤10) 和 m,分别是图的顶点数和边数。随后 m 行,每行给出一条边的两个端点。每行中的数字之间用 1 空格分隔。
输出格式:
按照"{ v1 v2 ... vk }"的格式,每行输出一个连通集。先输出 DFS 的结果,再输出 BFS 的结果。
输入样例:
8 6 0 7 0 1 2 0 4 1 2 4 3 5
输出样例:
{ 0 1 4 2 7 } { 3 5 } { 6 } { 0 1 2 7 4 } { 3 5 } { 6 }
邻接矩阵,这个最易理解,也很轻松,满分
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxVertex 10
#define MaxSize 10
bool Visited_DFS[MaxVertex];
bool Visited_BFS[MaxVertex];
typedef struct ENode *Edge;
struct ENode{
int V1, V2;
int Weight;
};
typedef struct GNode *PtrToGNode;
typedef PtrToGNode MGraph;
struct GNode{
int Nv;
int Ne;
bool G[MaxVertex][MaxVertex];
};
typedef struct Node *Queue;
struct Node{
int data[MaxSize];
int front;
int rear;
};
MGraph Creat_Graph(int Nv, int Ne);
void Insert_Graph(MGraph M, Edge E);
MGraph Build_Graph();
void Visit(int V);
Queue Init_Q();
void Add_Q(Queue Q, int Vertex);
int Delete_Q(Queue Q);
bool IsFull_Q(Queue Q);
bool IsEmpty_Q(Queue Q);
void List_DFS(MGraph M);
void List_BFS(MGraph M);
int main()
{
int Vertex;
MGraph M;
M = Build_Graph();
List_DFS(M);
List_BFS(M);
return 0;
}
MGraph Build_Graph()
{
MGraph MG;
Edge E;
int Nv, Ne, i, j;
scanf("%d%d", &Nv, &Ne);
MG = Creat_Graph(Nv, Ne);
E = (Edge)malloc(sizeof(struct ENode));
for(i = 0; i < (MG ->Ne); i++){
scanf("%d%d",&(E ->V1), &(E ->V2));
E ->Weight = 1;
Insert_Graph(MG, E);
}
for(j = 0; j < (MG ->Ne); j++){
Visited_DFS[j] = false;
Visited_BFS[j] = false;
}
return MG;
}
MGraph Creat_Graph(int Nv, int Ne)
{
MGraph M;
M = (MGraph)malloc(sizeof(struct GNode));
M ->Nv = Nv;
M ->Ne = Ne;
for(int i = 0; i < Nv; i++){
for(int j = 0; j < Nv; j++){
M ->G[i][j] = false;
}
}
return M;
}
void Insert_Graph(MGraph M, Edge E)
{
M ->G[E ->V1][E ->V2] = true;
M ->G[E ->V2][E ->V1] = true;
}
void Visit(int V)
{
printf(" %d", V);
}
void DFS(MGraph M, int Vertex, void(*Visit)(int))
{
int T;
Visited_DFS[Vertex] = true;
Visit(Vertex);
for(int i = 0; i < M ->Nv; i++){
if(!Visited_DFS[i] && M ->G[Vertex][i] == true){
DFS(M, i, Visit);
}
}
}
void BFS(MGraph M, int Vertex, void(*Visit)(int))
{
Queue Q;
int T, i;
Q = Init_Q();
Visit(Vertex);
Visited_BFS[Vertex] = true;
Add_Q(Q, Vertex);
while(!IsEmpty_Q(Q)){
T = Delete_Q(Q);
for(i = 0; i < M ->Nv; i++){
if(!Visited_BFS[i] && M ->G[T][i]){
Visit(i);
Visited_BFS[i] = true;
Add_Q(Q, i);
}
}
}
}
Queue Init_Q()
{
Queue Q;
Q = (Queue)malloc(sizeof(struct Node));
Q ->front = 0;
Q ->rear = 0;
return Q;
}
void Add_Q(Queue Q, int Vertex)
{
if(IsFull_Q(Q)){
printf("队列满!");
return ;
}
Q ->rear = (Q ->rear + 1) % MaxSize;
Q ->data[Q ->rear] = Vertex;
}
int Delete_Q(Queue Q)
{
if(IsEmpty_Q(Q)){
printf("队列空!");
return -1;
}else{
Q ->front = (Q ->front + 1) % MaxSize;
return Q ->data[Q ->front];
}
}
bool IsFull_Q(Queue Q)
{
return (Q ->rear + 1) % MaxSize == Q ->front;
}
bool IsEmpty_Q(Queue Q)
{
return Q ->front == Q ->rear;
}
void List_DFS(MGraph M)
{
for(int V=0; V < M->Nv;V++) {
if(!Visited_DFS[V]) {
printf("{");
DFS(M, V, Visit);
printf(" }");
printf("\n");
}
}
}
void List_BFS(MGraph M)
{
for(int V=0; V < M->Nv;V++) {
if(!Visited_BFS[V]) {
printf("{");
BFS(M, V, Visit);
printf(" }");
printf("\n");
}
}
}
这个是邻接表,完全动态分配,有点难度,249行,
其实怪耽误我时间呢,主要是队列处理,忘记了删除仅有一个节点的队列不需要释放空间,哎!排查好久。
这个是我认为的,比较有创新的地方,其实最开始想单拿,图M,作为参数,但发现会陷入无限循环,让我头疼死了,
后来晚上吃饭想明白,指哪里改哪里,或许有奇效,结果是对,哈哈,同时也证明了,逻辑没问题。
void Sort_Graph(PtrToAdjVNode *Link) { PtrToAdjVNode head, Temp, Key; head = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); head ->Next = (*Link) ->Next; Temp = head; Key = (*Link); Key ->Next = NULL; if(!(head ->Next)){ return ; } while(head ->Next){ if(Key ->V > (head ->Next ->V)){ head = head ->Next; }else{ Key ->Next = head ->Next; head ->Next = Key; break; } } if(!(head ->Next)){ head ->Next = Key; } (*Link) = Temp ->Next; return ; }
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct ENode *PtrToENode;
typedef PtrToENode Edge;
struct ENode{
int V1, V2;
int Weight;
};
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
int V;
int Weight;
PtrToAdjVNode Next;
};
typedef struct VNode **AdjList;
struct VNode{
PtrToAdjVNode FirstEdge;
};
typedef struct GNode *PtrToGNode;
typedef PtrToGNode LGraph;
struct GNode{
int Nv;
int Ne;
AdjList G;
};
typedef struct Node *QNode;
struct Node{
int Data;
QNode Next;
};
typedef struct QNode *Queue;
struct QNode{
QNode front;
QNode rear;
};
LGraph Build_Graph();
LGraph Init_Graph(int Nv, int Ne);
void Insert_Graph(LGraph M, Edge E);
void Sort_Graph(PtrToAdjVNode *Link);
void Visit(int Vertex);
void DFS(LGraph M, int Vertex, bool *Visited, void(*Visit)(int));
void BFS(LGraph M, int Vertex, bool *Visited, void(*Visit)(int));
void List_DFS(LGraph M);
void List_BFS(LGraph M);
Queue Init_Q();
void Add_Q(Queue Q, int Vertex);
int Delete_Q(Queue Q);
bool IsEmpty_Q(Queue Q);
int main()
{
LGraph M;
M = Build_Graph();
List_DFS(M);
List_BFS(M);
return 0;
}
LGraph Build_Graph()
{
LGraph M;
Edge E;
int Nv, Ne;
int i;
scanf("%d%d", &Nv, &Ne);
M = Init_Graph(Nv, Ne);
E = (Edge)malloc(sizeof(struct ENode));
if(M ->Nv){
for(i = 0; i < (M ->Ne); i++){
scanf("%d%d", &E ->V1, &E ->V2);
Insert_Graph(M, E);
}
}
return M;
}
LGraph Init_Graph(int Nv, int Ne)
{
LGraph M;
M = (LGraph)malloc(sizeof(struct GNode));
M ->Nv = Nv;
M ->Ne = Ne;
M ->G = (AdjList)malloc(sizeof(struct VNode) * Nv);
for(int i = 0; i < Nv; i++){
M ->G[i] = (struct VNode*)malloc(sizeof(struct VNode));
M ->G[i] ->FirstEdge = NULL;
}
return M;
}
void Insert_Graph(LGraph M, Edge E)
{
// 无向图
PtrToAdjVNode NewNode1, NewNode2;
NewNode1 = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode1 ->V = E ->V2;
NewNode1 ->Weight = E ->Weight;
NewNode1 ->Next = M ->G[E ->V1] ->FirstEdge;
M ->G[E ->V1] ->FirstEdge = NewNode1;
Sort_Graph(&(M ->G[E ->V1] ->FirstEdge));
NewNode2 = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode2 ->V = E ->V1;
NewNode2 ->Weight = E ->Weight;
NewNode2 ->Next = M ->G[E ->V2] ->FirstEdge;
M ->G[E ->V2] ->FirstEdge = NewNode2;
Sort_Graph(&(M ->G[E ->V2] ->FirstEdge));
}
void Sort_Graph(PtrToAdjVNode *Link)
{
PtrToAdjVNode head, Temp, Key;
head = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
head ->Next = (*Link) ->Next;
Temp = head;
Key = (*Link);
Key ->Next = NULL;
if(!(head ->Next)){
return ;
}
while(head ->Next){
if(Key ->V > (head ->Next ->V)){
head = head ->Next;
}else{
Key ->Next = head ->Next;
head ->Next = Key;
break;
}
}
if(!(head ->Next)){
head ->Next = Key;
}
(*Link) = Temp ->Next;
return ;
}
void Visit(int Vertex)
{
printf(" %d", Vertex);
}
void DFS(LGraph M, int Vertex, bool *Visited, void(*Visit)(int))
{
PtrToAdjVNode W;
Visit(Vertex);
Visited[Vertex] = true;
for(W = M ->G[Vertex] ->FirstEdge; W; W = W ->Next){
if(!Visited[W ->V]){
DFS(M, W ->V, Visited, Visit);
}
}
}
void BFS(LGraph M, int Vertex, bool *Visited, void(*Visit)(int))
{
Queue Q;
PtrToAdjVNode G;
int V;
Q = Init_Q();
Visited[Vertex] = true;
Visit(Vertex);
Add_Q(Q, Vertex);
while(!IsEmpty_Q(Q)){
V = Delete_Q(Q);
for(G = M ->G[V] ->FirstEdge; G; G = G ->Next){
if(Visited[G ->V] == false){
Visit(G ->V);
Visited[G ->V] = true;
Add_Q(Q, G ->V);
}
}
}
}
Queue Init_Q()
{
Queue Q;
Q = (Queue)malloc(sizeof(struct QNode));
Q ->front = NULL;
Q ->rear = Q ->front;
return Q;
}
void Add_Q(Queue Q, int Vertex)
{
QNode Node;
Node = (QNode)malloc(sizeof(struct Node));
Node ->Data = Vertex;
Node ->Next = NULL;
if(!(Q ->front) && !(Q ->rear)){
Q ->front = Node;
Q ->rear = Node;
}else{
Q ->rear ->Next = Node;
Q ->rear = Node;
}
}
int Delete_Q(Queue Q)
{
if(IsEmpty_Q(Q)){
printf("很遗憾,是空的!\n");
return -1;
}else{
QNode Temp;
int Vertex;
if(Q ->front == Q ->rear){
Vertex = Q ->front ->Data;
Q ->front = NULL;
Q ->rear = NULL;
}else{
Temp = Q ->front;
Q ->front = Q ->front ->Next;
Vertex = Temp ->Data;
free(Temp);
}
return Vertex;
}
}
bool IsEmpty_Q(Queue Q)
{
return Q ->front == NULL;
}
void List_DFS(LGraph M)
{
bool *Visited;
Visited = (bool*)calloc(M ->Nv, sizeof(bool));
for(int V=0; V < M->Nv;V++) {
if(!Visited[V]) {
printf("{");
DFS(M, V, Visited, Visit);
printf(" }");
printf("\n");
}
}
free(Visited);
}
void List_BFS(LGraph M)
{
bool *Visited;
Visited = (bool*)calloc(M ->Nv, sizeof(bool));
for(int V=0; V < M->Nv;V++) {
if(!Visited[V]) {
printf("{");
BFS(M, V, Visited, Visit);
printf(" }");
printf("\n");
}
}
free(Visited);
}