目录
深度优先搜索
/*
创建无向图并深度优先搜索
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100
typedef struct ArcCell {
char vexnum[MAXN]; //顶点
int arcnum[MAXN][MAXN]; //弧
int n, e; //顶点数, 弧数
}Graph;
int Visit[MAXN] = { 0 }; //定义Visit来判断顶点是否被访问,并初始化
void CreateGraph(Graph* G) { //创建图 ,此处注意&G
int s, t;
scanf_s("%d %d", &G->n, &G->e);
getchar();
for (int i = 0; i < G->n; i++) {
scanf_s("%c", &G->vexnum[i],1);
getchar();
}
for (int i = 0; i < G->n; i++) { //初始化数据
for (int j = 0; j < G->n; j++) {
G->arcnum[i][j] = 0;
}
}
for (int i = 0; i < G->e; i++) { //创建图的邻接矩阵
scanf_s("%d %d", &s, &t);
G->arcnum[s][t] = 1;
G->arcnum[t][s] = 1;
}
}
//int Visit[MAXN] = { 0 };
//开始搜索 找一个开始结点
//但是一个图,没有所谓的第一个结点
//开始结点是人定义的
//需要遍历的图G 遍历的起始结点从i开始
//标记结点
//1.遍历未被标记的结点
//2.如果遍历到某一个邻接点已被标记 我要继续找和我相邻的另外一个结点
void DFSTraverse(Graph G, int i) {//找邻接点
printf("%c", G.vexnum[i]);
for (int j = 0; j < G.n; j++) {
if (G.arcnum[i][j] && !Visit[j]) {
Visit[j] = 1;
DFSTraverse(G, j);
}
}
}
void DFS(Graph G) {//遍历未被标记的结点
for (int i = 0; i < G.n; i++)//对整个图的结点进行深搜
{
if (!Visit[i]) {
Visit[i] = 1;
DFSTraverse(G, i);
}
}
}
int main()
{
Graph G;
CreateGraph(&G);
DFS(G);
}
测试一下
广度优先搜索
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERtEX_NUM 20 //顶点的最大个数
#define VRType int //表示顶点之间的关系的变量类型
#define InfoType char //存储弧或者边额外信息的指针变量类型
#define VertexType int //图中顶点的数据类型
//typedef enum { false, true }bool; //定义bool型常量
bool visited[MAX_VERtEX_NUM]; //设置全局数组,记录标记顶点是否被访问过
typedef struct Queue {
VertexType data;
struct Queue* next;
}Queue;
typedef struct {
VRType adj; //对于无权图,用 1 或 0 表示是否相邻;对于带权图,直接为权值。
InfoType* info; //弧或边额外含有的信息指针
}ArcCell, AdjMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM];
typedef struct {
VertexType vexs[MAX_VERtEX_NUM]; //存储图中顶点数据
AdjMatrix arcs; //二维数组,记录顶点之间的关系
int vexnum, arcnum; //记录图的顶点数和弧(边)数
}MGraph;
int LocateVex(MGraph* G, int v);
//构造无向图
void CreateDN(MGraph* G) {
scanf_s("%d,%d", &(G->vexnum), &(G->arcnum));
for (int i = 0; i < G->vexnum; i++) {
scanf_s("%d", &(G->vexs[i]));
}
for (int i = 0; i < G->vexnum; i++) {
for (int j = 0; j < G->vexnum; j++) {
G->arcs[i][j].adj = 0;
G->arcs[i][j].info = NULL;
}
}
for (int i = 0; i < G->arcnum; i++) {
int v1, v2;
scanf_s("%d,%d", &v1, &v2);
int n = LocateVex(G, v1);
int m = LocateVex(G, v2);
if (m == -1 || n == -1) {
printf("no this vertex\n");
return;
}
G->arcs[n][m].adj = 1;
G->arcs[m][n].adj = 1;//无向图的二阶矩阵沿主对角线对称
}
}
//操作顶点的函数
void visitVex(MGraph G, int v) {
printf("%d ", G.vexs[v]);
}
//初始化队列
void InitQueue(Queue** Q) {
(*Q) = (Queue*)malloc(sizeof(Queue));
(*Q)->next = NULL;
}
//顶点元素v进队列
void EnQueue(Queue** Q, VertexType v) {
Queue* element = (Queue*)malloc(sizeof(Queue));
element->data = v;
element->next = NULL;
Queue* temp = (*Q);
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = element;
}
//队头元素出队列
void DeQueue(Queue** Q, int* u) {
(*u) = (*Q)->next->data;
(*Q)->next = (*Q)->next->next;
}
//判断队列是否为空
bool QueueEmpty(Queue* Q) {
if (Q->next == NULL) {
return true;
}
return false;
}
int LocateVex(MGraph* G, int v) {
for (int i = 0; i < G->vexnum; i++) {
if (G->vexs[i] == v) {
return i;
}
}
return -1;
}
int FirstAdjVex(MGraph G, int v) {
for (int i = 0; i < G.vexnum; i++) {
if (G.arcs[v][i].adj) {
return i;
}
}
return -1;
}
int NextAdjVex(MGraph G,int v,int w) {
for (int i = w+1; i < G.vexnum; i++)
{
if (G.arcs[v][i].adj) {
return i;
}
}
return -1;
}
void BFSTraverse(MGraph G) {
for (int i = 0; i < G.vexnum; i++)
{
visited[i] = 0;
}
Queue* Q;
InitQueue(&Q);
for (int i = 0; i < G.vexnum; i++)
{
if (!visited[i]) {
visited[i] = 1;
printf("%d", G.vexs[i]);
EnQueue(&Q, G.vexs[i]);
while (!QueueEmpty(Q)) {
int u;//出队元素的值
DeQueue(&Q,&u);
//先定位下标
u = LocateVex(&G, u);
//从第一个和下标u有关的顶点位置开始,到下一个跟我有关系的点
for (int w = FirstAdjVex(G,u); w >= 0; w=NextAdjVex(G,u,w))
{
if (!visited[w]) {
visited[w] = 1;
printf("%d", G.vexs[w]);
EnQueue(&Q, G.vexs[w]);
}
}
}
}
}
}
int main() {
MGraph G;
CreateDN(&G);
BFSTraverse(G);
return 0;
}
测试一下