初学图

图的基本概念


在线性表中,数据元素之间是被串起来的,仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继。在树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素可能和下一层中多个元素相关,但只能和上一层中一个元素相关。图是一种较线性表和树更加复杂的数据结构。在图形结构中,结点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。

图的一些概念

1、有向图

若E是有向边(也称弧)的有限集合时,则图G为有向图。弧是顶点的有序对,记为,其中v,w是顶点,v称为弧尾,w称为弧头,称为从顶点v到顶点w的弧,也称v邻接到w,或w邻接自v。

2、无向图

若E是无向边(简称边)的有限集合时,则图G为无向图。边是顶点的无序对,记为(v, w)或(w,v),因为(v,w)=(w,v), 其中v,w是顶点。可以说顶点w和顶点v互为邻接点。边(v, w)依附于顶点w和v,或者说边(v, w)和顶点v, w相关联。

3、多重图
若图G GG中某两个结点之间的边数多于一条,又允许顶点通过同一条边和自己关联,则G GG为多重图。多重图的定义和简单图是相对的。

4、完全图(也称简单完全图)
对于无向图,∣ E ∣ |E|∣E∣的取值范围是0 00到n ( n − 1 ) / 2 n(n-1)/2n(n−1)/2,有n ( n − 1 ) / 2 n(n -1)/2n(n−1)/2条边的无向图称为完全图,在完全图中任意两个顶点之间都存在边。对于有向图,∣ E ∣ |E|∣E∣的取值范围是0 00到n ( n − 1 ) n(n-1)n(n−1),有n ( n − 1 ) n(n-1)n(n−1)条弧的有向图称为有向完全图,在有向完全图中任意两个顶点之间都存在方向相反的两条弧。

5、连通、连通图和连通分量
在无向图中,若从顶点v vv到顶点w ww有路径存在,则称v vv和w ww是连通的。若图G GG中任意两个顶点都是连通的,则称图G GG为连通图,否则称为非连通图。无向图中的极大连通子图称为连通分量。若一个图有n nn个顶点,并且边数小于n − 1 n-1n−1,则此图必是非连通图。

6、边的权和网
在一个图中,每条边都可以标上具有某种含义的数值,该数值称为该边的权值。这种边上带有权值的图称为带权图,也称网。

7、稠密图、稀疏图
边数很少的图称为稀疏图,反之称为稠密图。稀疏和稠密本身是模糊的概念,稀疏图和稠密图常常是相对而言的。一般当图G满足∣ E ∣ < ∣ V ∣ l o g ∣ V ∣ |E| < |V|log|V|∣E∣<∣V∣log∣V∣时,可以将G GG视为稀疏图。

8、 简单路径、简单回路
在路径序列中,顶点不重复出现的路径称为简单路径。除第一个顶点和最后一个顶点外,其余顶点不重复出现的回路称为简单回路。

9、距离
从顶点u uu出发到顶点v vv的最短路径若存在,则此路径的长度称为从u uu到v vv的距离。若从u uu到v vv根本不存在路径,则记该距离为无穷( ∞ ) 。

10、有向树
一个顶点的入度为0、其余顶点的入度均为1的有向图,称为有向树。

创建图

用邻接矩阵实现

邻接矩阵是一种用矩阵表示顶点之间相邻关系的方法。对于一个有n个顶点的图,其邻接矩阵是一个n x n的矩阵,矩阵中的元素表示顶点之间的边的权重。如果两个顶点之间没有边连接,则对应的元素为0。

#include 
#include 

#define MaxVertexnum 100

typedef int ElemType;

typedef struct graph {
int Nv; // 顶点数
int Ne; // 边数
int Data[MaxVertexnum]; // 存放顶点数据
int Weight[MaxVertexnum][MaxVertexnum]; // 存放权重
} graph, *MGraph;

typedef struct edge {
int V1, V2; // V1到V2
int Weight; // 边的权重
} *Edge;

// 初始化图
void InitGraph(MGraph G, int Vertnex) {
G->Nv = Vertnex; // 顶点数
G->Ne = 0; // 边数为0
for (int i = 0; i < Vertnex; i++) {
for (int j = 0; j < Vertnex; j++) {
G->Weight[i][j] = 0; // 初始化权重为0
}
}
}

// 插入边的权重
void InsertEdge(MGraph G, Edge E) {
G->Weight[E->V1][E->V2] = E->Weight;
G->Weight[E->V2][E->V1] = E->Weight;
}

用邻接表实现

邻接表是一种链式存储结构,用于表示图中的每个顶点及其相邻的顶点。每个顶点都有一个链表,链表中的结点存放与该顶点相邻的顶点信息。

typedef struct node {
	int weight; // 存放权重
	struct node* next; // 指向下一个边结点
	int local; // 该边指向的顶点
} EdgeNode;
typedef struct VNode {
	int data; // 顶点数据
	node* firstVertnex; // 指向边
} VNode, AdjList[MaxVertexnum];
typedef struct Adjgraph {
	int Nv; // 顶点数
	int Ne; // 边数
	AdjList List; // 邻接表
} AdjMGraph;
// 初始化邻接表
void InitAdjGraph(AdjMGraph* G) {
	printf("请输入顶点数和边数(空格分隔)!\n");
	scanf("%d %d", &G->Nv, &G->Ne);
	printf("请输入顶点数据:\n");
	for (int i = 1; i <= G->Nv; i++) {
		printf("第%d个顶点数据为:\n", i);
		scanf("%d", &G->List[i].data);
		G->List[i].firstVertnex = NULL;
	}
}
// 创建邻接表
void A(AdjMGraph* G) {
	printf("一共有%d条边!\n", G->Ne);
	printf("请输入两个顶点以及二者之间的权重(中间用空格分隔):\n");
	int W, V, weight;
	for (int i = 1; i <= G->Ne; i++) {
		scanf("%d %d %d", &W, &V, &weight);
		node* p = (node*)malloc(sizeof(node));
		p->local = V;
		p->weight = weight;
		p->next = G->List[W].firstVertnex;
		G->List[W].firstVertnex = p;
		node* q = (node*)malloc(sizeof(node));
		q->local = W;
		q->weight = weight;
		q->next = G->List[V].firstVertnex;
		G->List[V].firstVertnex = q;
	}
}

你可能感兴趣的:(图论,算法)