无向图创建邻接矩阵、深度优先遍历和广度优先遍历
一、概念解析:
(1)无向图:
假设图G由两个集合V和E组成,记为G={V , E}。其中V是顶点的有限集合,E是连接V中两个不同顶点的边的有限集合。如果E中的顶点对是有序的,即E中的每条边都是有方向的,则称G是有向图。如果顶点对是无序的,则称G是无向图
(2)邻接矩阵:
邻接矩阵主要由:二维数组 实现
如图
转换成邻接矩阵为:
二、创建邻接矩阵:
基本每一步都有注释,详细观看,建议画图理解
代码如下:
#define MAXSIZE 100
// 邻接矩阵
typedef struct Matrix{
int V_Data; // 顶点数据域
int E_Data; // 边数数据域
int Node[MAXSIZE]; // 存放顶点数据,也就是顶点表
int Weight[MAXSIZE][MAXSIZE]; // 存放权重,为矩阵中两点有边的标记符号
}MaTrix,*MATRIX;
// 邻接矩阵数据结构体
typedef struct Edge{
int v1; // 用来存放第一个顶点
int v2; // 用来存放第二个顶点
int weight; // 用来存放两点之间的标记符,即为权
}*EDGE;
//******************** 邻接矩阵*******************//
// 邻接矩阵、顶点和边初始化
void Init_Matrix(MATRIX S,int Vertex)
{
S->E_Data = 0; // 初始化为0条边
S->V_Data = Vertex; // 初始化顶点数
int i,j;
for(i=0;i<Vertex;i++)
{
for(j=0;j<Vertex;j++)
{
S->Weight[i][j] = 0;
}
}
}
// 开始插入边的权重,即为两个顶点之间边的标记符
void InSerData(MATRIX S,EDGE E)
{
// 将输入的顶点v1、v2之间的边,用权作为标记,在矩阵中表示
// 这里是无向图,所以边没有方向,需要做标记两次(为v1-v2和v2-v1)
S->Weight[E->v1][E->v2] = E->weight;
S->Weight[E->v2][E->v1] = E->weight;
}
// 开始插入数据
void InSerEdge_Data(MATRIX S,int edge,int V)
{
int i,j;
if(edge>0) // 边数大于0的时候才插入数据
{
printf("请输入顶点和权重(空格分隔!)\n");
for(i=0;i<edge;i++)
{
EDGE E; //分配内存,接受顶点v1,v2和权重(标记符)
E = (EDGE)malloc(sizeof(struct Edge));
scanf("%d %d %d",&(E->v1),&(E->v2),&(E->weight));
if(E->v1 ==E->v2)
{
printf("无向图邻接矩阵对角线为0,输入错误,结束运行\n");
exit(-1);
}
InSerData(S,E);
}
printf("请输入要定义的顶点,填入顶点表中: \n");
for(j=0;j<V;j++)
{
scanf("%d",&(S->Node[j]));
}
}else{
printf("输入的边数错误");
}
}
三、深度遍历、广度遍历
(1)深度遍历概念:
定义的结构体、数组可看上面代码
深度遍历代码解析:
//***************** 深度优先遍历算法—邻接矩阵 *****************//
void DFS_Begin(MATRIX P,int k,int V)
{
int i;
flag[k] = 1; //标记当前顶点,表示已经遍历过
printf(