- 题目来源:
浙江大学在慕课网上开设的《数据结构》课,陈越老师、何钦铭老师主讲,课后作业的一道题。
- 题目描述:
- 思路:
非常基础的一道题,主要考察图的DFS遍历和BFS遍历,最后注意输出的格式就可以了。
- C语言实现:
#include
#include
#include
#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; //有向边
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)
{
////插入边
//Graph->G[E->V1][E->V2] = E->Weight;
////若是无向图,还需要插入
//Graph->G[E->V2][E->V1] = E->Weight;
//插入边
Graph->G[E->V1][E->V2] = 1;
//若是无向图,还需要插入
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;
}