一、图的遍历的相关定义
二、深度优先搜索
void PreOrder(TreeNode* R)
{if (R != NULL){visit(R);//访问根结点while (R还有下一个子树T){PreOrder(T);//先根遍历下一棵子树}}
}
基于邻接矩阵的深度优先遍历
bool visited[MAXV];//访问标记数组
void DFS(MGraph G, int v);//从第v个顶点开始,深度优先遍历
{visit(v);//访问第v个顶点visited[v] = true;//将第v个顶点设置为已经访问的标记for (int w = FirstNeighbor(G, v); w > 0; w = NextNeighbor(G, v, w)){if (!visited[w])//第w个顶点为第v个顶点尚未访问的邻接点{DFS(G, w);}}
}注意;
int FirstNeighbor(MGraph G, int x);//求图G中顶点x的第一个邻接点,若有则返回顶点号;
//若没有邻接点或图中不存在x,则返回-1
int NextNeighbor(MGraph G, int x, int y);
//假设图G中第y个顶点是第x个顶点的一个邻接点,
//返回除第y个顶点之外,第x个顶点的下一个邻接点的顶点号;若第y个顶点是第x个顶点的最后一个邻接点,则返回-1
#pragma once
#include
#include
#include
using namespace std;#define MaxVertexNum 100//顶点数目的最大值
//#define INFINITY 100000//宏定义常量“无穷”
#define MAXV 100typedef int VertexType;//顶点的数据类型
//typedef char VertexType;//顶点的数据类型
typedef int EdgeType;//带权图中边上权值的数据类型
typedef struct
{VertexType vexs[MaxVertexNum];//顶点表(存放顶点)EdgeType edges[MaxVertexNum][MaxVertexNum];//邻接矩阵,边表(存放任意两个顶点之间的距离)int n, e;//图的当前顶点数和边数/弧数
}MGraph;void CreatMat(MGraph& G, int A[][MAXV], int n);//由数组A[n][n]生成邻接矩阵G
//生成图的邻接矩阵方法1
void DisMGraph(MGraph& G);//打印void Init(MGraph& G);//初始化,将所有顶点都初始化为没有访问的顶点
void DFS(MGraph G, int v);//从第v个顶点开始,深度优先遍历
int FirstNeighbor(MGraph G, int x);//求图G中顶点x的第一个邻接点,若有则返回顶点号;
//若没有邻接点或图中不存在x,则返回-1
int NextNeighbor(MGraph G, int x, int y);//假设图G中顶点y是顶点x的一个邻接点,
//返回除y之外顶点x的下一个邻接点的顶点号;若y是x的最后一个邻接点,则返回-1
#include"MGraph.h"void CreatMat(MGraph& G, int A[][MAXV], int n)//由数组A[n][n]生成邻接矩阵G
{G.n = n;G.e = 0;cout << "请依次输入顶点信息:";for (int i = 1; i <= G.n; i++){cin >> G.vexs[i];}for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){G.edges[i + 1][j + 1] = A[i][j];//i+1,j+1是为了从为了从二维数组[1][1]开始存储if (A[i][j] != 0 && A[i][j] != INFINITY){G.e++;//边数加1}}}
}
void DisMGraph(MGraph& G)//遍历打印
{for (int i = 1; i <= G.n; i++){for (int j = 1; j <= G.n; j++){cout << G.edges[i][j] << " ";}cout << endl;}
}bool visited[MAXV];//访问标记数组
void Init(MGraph& G)//初始化
{for (int i = 1; i <= G.n; i++){visited[i] = false;//标记为访问}
}void DFS(MGraph G, int v)//从第v个顶点(下标也是v)开始,深度优先遍历
{cout << G.vexs[v] << " ";//访问第v个顶点visited[v] = true;//将第v个顶点改为已经访问的标记for (int w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)){if (!visited[w]){DFS(G, w);}}
}int FirstNeighbor(MGraph G, int x)//求图G中第x个顶点的第一个邻接点,若有则返回顶点号;
//若没有邻接点或图中不存在x,则返回-1
{for (int j = 1; j <= G.n; j++){if (G.edges[x][j] == 1)//寻找第x个顶点的第一个邻接点{return j;//返回第x个顶点的第一个邻接点的顶点号}}return -1;
}
int NextNeighbor(MGraph G, int x, int y)//假设图G中第y个顶点是第x个顶点的一个邻接点,
//返回除第y个顶点之外,第x个顶点的下一个邻接点的顶点号;若第y个顶点是第x个顶点的最后一个邻接点,则返回-1
{int i = 1, j = 1;for (int k = y + 1; k <= G.n; k++)//在邻接矩阵第x个顶点所在行//从第y个顶点之后寻找与第x个顶点邻接的顶点{if (G.edges[x][k] == 1){return k;}}return -1;
}
#include"MGraph.h"
int main()
{MGraph G;int A[][MAXV] = { {0,1,0,0,1,0,0,0},{1,0,0,0,0,1,0,0},{0,0,0,1,0,1,1,0},{0,0,1,0,0,0,1,1},{1,0,0,0,0,0,0,0},{0,1,1,0,0,0,1,0}, {0,0,1,1,0,1,0,1},{0,0,0,1,0,0,1,0} };CreatMat(G, A, 8);//方法1cout << "图的邻接矩阵:" << endl;DisMGraph(G);cout << endl;/*cout << G.vexs[4] << endl;cout<
void DFSTraverse(MGraph G)//对图G进行深度优先遍历
{Init(G);//初始化for (int v = 1; v <= G.n; v++){if (!visited[v])//对每个连通分量调用一次DFS{DFS(G, v);}}
}
#pragma once
#include
#include
#include
using namespace std;#define MaxVertexNum 100//顶点数目的最大值
//#define INFINITY 100000//宏定义常量“无穷”
#define MAXV 100typedef int VertexType;//顶点的数据类型
//typedef char VertexType;//顶点的数据类型
typedef int EdgeType;//带权图中边上权值的数据类型
typedef struct
{VertexType vexs[MaxVertexNum];//顶点表(存放顶点)EdgeType edges[MaxVertexNum][MaxVertexNum];//邻接矩阵,边表(存放任意两个顶点之间的距离)int n, e;//图的当前顶点数和边数/弧数
}MGraph;void CreatMat(MGraph& G, int A[][MAXV], int n);//由数组A[n][n]生成邻接矩阵G
//生成图的邻接矩阵方法1
void DisMGraph(MGraph& G);//打印void Init(MGraph& G);//初始化,将所有顶点都初始化为没有访问的顶点
void DFS(MGraph G, int v);//从第v个顶点开始,深度优先遍历
int FirstNeighbor(MGraph G, int x);//求图G中顶点x的第一个邻接点,若有则返回顶点号;
//若没有邻接点或图中不存在x,则返回-1
int NextNeighbor(MGraph G, int x, int y);
//假设图G中第y个顶点是第x个顶点的一个邻接点,
//返回除第y个顶点之外,第x个顶点的下一个邻接点的顶点号;若第y个顶点是第x个顶点的最后一个邻接点,则返回-1
void DFSTraverse(MGraph G);//对图G进行深度优先遍历(图G可以是非连通图)
#include"MGraph.h"void CreatMat(MGraph& G, int A[][MAXV], int n)//由数组A[n][n]生成邻接矩阵G
{G.n = n;G.e = 0;cout << "请依次输入顶点信息:";for (int i = 1; i <= G.n; i++){cin >> G.vexs[i];}for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){G.edges[i + 1][j + 1] = A[i][j];//i+1,j+1是为了从为了从二维数组[1][1]开始存储if (A[i][j] != 0 && A[i][j] != INFINITY){G.e++;//边数加1}}}
}
void DisMGraph(MGraph& G)//遍历打印
{for (int i = 1; i <= G.n; i++){for (int j = 1; j <= G.n; j++){cout << G.edges[i][j] << " ";}cout << endl;}
}bool visited[MAXV];//访问标记数组
void Init(MGraph& G)//初始化
{for (int i = 1; i <= G.n; i++){visited[i] = false;//标记为访问}
}void DFS(MGraph G, int v)//从第v个顶点(下标也是v)开始,深度优先遍历
{cout << G.vexs[v] << " ";//访问第v个顶点visited[v] = true;//将第v个顶点改为已经访问的标记for (int w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)){if (!visited[w]){DFS(G, w);}}
}int FirstNeighbor(MGraph G, int x)//求图G中第x个顶点的第一个邻接点,若有则返回顶点号;
//若没有邻接点或图中不存在x,则返回-1
{for (int j = 1; j <= G.n; j++){if (G.edges[x][j] == 1)//寻找第x个顶点的第一个邻接点{return j;//返回第x个顶点的第一个邻接点的顶点号}}return -1;
}
int NextNeighbor(MGraph G, int x, int y)//假设图G中第y个顶点是第x个顶点的一个邻接点,
//返回除第y个顶点之外,第x个顶点的下一个邻接点的顶点号;若第y个顶点是第x个顶点的最后一个邻接点,则返回-1
{int i = 1, j = 1;for (int k = y + 1; k <= G.n; k++)//在邻接矩阵第x个顶点所在行//从第y个顶点之后寻找与第x个顶点邻接的顶点{if (G.edges[x][k] == 1){return k;}}return -1;
}void DFSTraverse(MGraph G)//对图G进行深度优先遍历
{Init(G);//初始化for (int v = 1; v <= G.n; v++){if (!visited[v])//对每个连通分量调用一次DFS{DFS(G, v);}}
}
基于邻接表的深度优先遍历
int visited[MAXV] = { 0 };
void DFSA(AGraph* G, int i)//邻接表的深度优先算法,i表示从第i个顶点开始深度优先遍历
{ArcNode* p;visited[i] = 1;cout << G->adjlist[i].data<<" ";//访问顶点vip = G->adjlist[i].firstarc;//取vi边表的头指针while (p)//寻找vi的邻接点vj{if (!visited[p->adjvex])//若vj尚且未被访问,则以vj为出发点向纵深搜索{DFSA(G, p->adjvex);}p = p->nextarc;//找vi的下一个邻接点}
}
#pragma once
#include
#include
#include
using namespace std;//输入流的头文件
#include
#include
#include
#define txtRows 8 //txt行数
#define txtCols 8 //txt列数typedef int ElemType;
typedef int InfoType;
#define MAXV 100
#define INF 10000
typedef struct ANode//边结点类型
{int adjvex;//该边的终点位置struct ANode* nextarc;//指向一下条边的指针InfoType info;//该边的相关信息,如带权图可存放权重
}ArcNode;typedef struct Vode//表头结点的类型
{ElemType data;//顶点信息ArcNode* firstarc;//指向第一条边
}VNode;typedef VNode AdjList[MAXV]; //AdjList是邻接表类型
typedef struct
{AdjList adjlist;//邻接表(表头结点组成一个数组)int n, e;//定义顶点数和边数
}AGraph;//图的领接表类型void CreatAdj(AGraph*& G, int A[][MAXV], int n);//由数组A[n][n]生成邻接矩阵G
//生成图的邻接表
void DisAdj(AGraph* G);//打印
void DFSA(AGraph* G, int i);//邻接表的深度优先算法,i表示从第i个顶点开始深度优先遍历
#include"AGraph.h"void CreatAdj(AGraph*& G, int A[][MAXV], int n)//由数组A[n][n]生成邻接表G
{G = (AGraph*)malloc(sizeof(AGraph));//分配邻接表空间G->n = n;G->e = 0;cout << "请依次输入顶点信息:";for (int i = 1; i <= n; i++)//邻接表的所有表头结点的指针域都设置为空{cin >> G->adjlist[i].data;G->adjlist[i].firstarc = NULL;}ArcNode* p = NULL;for (int i = 0; i < n; i++){for (int j = n - 1; j >= 0; j--){if (A[i][j] != 0 && A[i][j] != INF)//存在一条边{p = (ArcNode*)malloc(sizeof(ArcNode));//创建一个边结点pp->adjvex = j+1;//该边的终点p->info = A[i][j];//该边的权重p->nextarc = G->adjlist[i+1].firstarc;//将新边结点p用头插法插入到顶点Vi的边表头部G->adjlist[i+1].firstarc = p;G->e++;//对于无向图,边数需要除以2}}}
}void DisAdj(AGraph* G)//打印
{ArcNode* p;for (int i = 1; i <= G->n; i++){cout << "[" << i << "]" << G->adjlist[i].data;p = G->adjlist[i].firstarc;//找到顶点i的第一个邻接点while (p != NULL){cout << "->";cout << p->adjvex;p = p->nextarc;//找到下一个邻接点}cout << endl;}
}int visited[MAXV] = { 0 };
void DFSA(AGraph* G, int i)//邻接表的深度优先算法,i表示从第i个顶点开始深度优先遍历
{ArcNode* p;visited[i] = 1;cout << G->adjlist[i].data<<" ";//访问顶点vip = G->adjlist[i].firstarc;//取vi边表的头指针while (p)//寻找vi的邻接点vj{if (!visited[p->adjvex])//若vj尚且未被访问,则以vj为出发点向纵深搜索{DFSA(G, p->adjvex);}p = p->nextarc;//找vi的下一个邻接点}
}
#include"AGraph.h"
int main()
{int A[MAXV][MAXV];FILE* fp;errno_t err = fopen_s(&fp, "C:\\Users\\86173\\Desktop\\Data1.txt", "r");//注意:Data.txt的属性中显示的是C:\Users\86173\Desktop//需要将单斜杠变双斜杠,双斜杠变四斜杠if (fp == NULL){cout << "文件读取错误!";return -1;}for (int i = 0; i < txtRows; i++){for (int j = 0; j < txtCols; j++){fscanf_s(fp, "%d", &A[i][j]);/*每次读取一个数,fscanf_s函数遇到空格或者换行结束*/}fscanf_s(fp, "\n");}fclose(fp);AGraph* G;CreatAdj(G, A, 8);cout << "邻接表形式:" << endl;DisAdj(G);cout << endl<<"邻接表的深度遍历序列为:";DFSA(G, 2);return 0;
}
0 1 0 0 1 0 0 0
1 0 0 0 0 1 0 0
0 0 0 1 0 1 1 0
0 0 1 0 0 0 1 1
1 0 0 0 0 0 0 0
0 1 1 0 0 0 1 0
0 0 1 1 0 1 0 1
0 0 0 1 0 0 1 0