图的定义
图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。
关于图的各种定义
- 无向边:若顶点
到
之间的边没有方向,则称这条边为无向边(Edge)。
- 无向图:若图中任意两个顶点之间的边都是无向边,则称该图为无向图。如果任意两个顶点都存在边,则称该图为无向完全图。含有n个顶点的完全无向图有n(n-1)/2条边。
- 有向边:若顶点
到
之间的边有方向,则称这条边为有向边,也称为弧(Arc)。用有序偶<
,
>,
表示头,
表示尾。
- 有向图:如果图中任意两个顶点之间的边都是有向边,则称该图为有向图。如果任意两个顶点都存在方向互为相反的边,则称该图为有向完全图。含有n个顶点的有向完全图有n(n-1)条边。
图的表示
邻接矩阵
邻接矩阵优点
- 方便检查任意一对顶点间是否存在边
- 方便查找任一顶点的所有“邻接点”
- 方面计算任一顶点的“度”
邻接矩阵缺点
- 浪费时间(统计稀疏图中一共有多少边)
- 浪费空间(点很多,边很少)
邻接表
邻接表优点
- 方便查找任一顶点的邻接点
- 节约稀疏图的空间,需要N个头指针 2E个节点
邻接表缺点
- 不方面检查任意一对顶点是否存在边
- 对有向图只能计算出度;需要构造“逆邻接表”来计算入度
邻接矩阵建图
代码语言:javascript复制#include <stdio.h>
#include <stdlib.h>
#include "io.h"
#include "math.h"
#include "time.h"
#define ERROR 0
#define OK 1
#define FALSE 0
#define TRUE 1
#define MAXVEX 20
#define INFINITY 65535
typedef char VertexType;
typedef int Status;
typedef int EdgeType;
//定义图的结构
typedef struct {
VertexType vexs[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
int numNode,numEdge;
}Mgraph;
//建立无向网图
void CreatMgraph(Mgraph *G)
{
int i, j, k, W;
printf("请输入顶点数和边数: n");
scanf("%d,%d",&G->numNode,&G->numEdge);
for(i=0; i<G->numNode; i ){
printf("请输入第%d个顶点n",i 1);
scanf("%cn",&G->vexs[i]);
} //输入顶点
for(j=0; j<G->numNode; j )
for(k=0; k<G->numNode; k ){
G->arc[j][k] = INFINITY;
} //初始化图
for(k=0; k<G->numEdge; k ){
printf("输入Vi,Vj的下标i,j和权值W");
scanf("%d%d%d",&i,&j,&W);
G->arc[i][j] = W;
G->arc[j][i] = W;
}//设置边的权值
}
int main()
{
Mgraph G;
CreatMgraph(&G);
return 0;
}
邻接表建图
代码语言:javascript复制#include <stdio.h>
#include <stdlib.h>
#include "io.h"
#include "math.h"
#include "time.h"
#define ERROR 0
#define OK 1
#define FALSE 0
#define TRUE 1
#define MAXVEX 20
#define INFINITY 65535
typedef int VertexType;
typedef int Status;
typedef int EdgeType;
typedef struct EdgeNode //定义边表节点
{
int vex; //节点下标
EdgeType W; //边的权值
struct EdgeNode *Next;
}EdgeNode;
typedef struct VertexNode //定义顶点表节点
{
VertexType data;
EdgeNode *first;
}VertexNode, VerList[MAXVEX];;
typedef struct
{
VerList verList;
int numEdge,numNode;
}Lgraph; //定义图结构
void CreateLgraph(Lgraph *G)
{
int i, j, k;
EdgeNode *e;
printf("输入节点数和边数:n");
scanf("%d,%d",&G->numNode,&G->numEdge);
for(i=0; i<G->numNode; i ){
scanf("%d",&G->verList[i].data);
G->verList->first = NULL;
}//输入顶点,初始化边节点
for(k=0; k<G->numEdge; k ){
printf("输入边(vi,vj)上的顶点序号:n");
scanf("%d,%d",&i,&j);
e = (EdgeNode*)malloc(sizeof(EdgeNode)); //新建一个边节点
e->vex = j;
e->Next = G->verList[i].first;
G->verList[i].first = e;
e = (EdgeNode*)malloc(sizeof(EdgeNode));
e->vex = i;
e->Next = G->verList[j].first;
G->verList[j].first = e;
}
}
int main()
{
Lgraph G;
CreateLgraph(&G);
return 0;
}