一 图的定义
图G由两个集合V和E组成,记为 G = ( V , E )
V是顶点的有穷非空集合,E是V中顶点偶对的有穷集,
这些顶点偶对称为边。通常V(G)和E(G)分别称为图的顶点集合和边集合。
注: E(G)可以为空集。
二,分类
图又分为有向图和无向图,个人理解数据间有无箭头
同时,把描述边的信息的数据叫做权值,又分了有权无权
端点和邻接点:
在一个无向图中,若存在一条边<vi,vj>, 则称vi,vj为该边的两个端点,
并称它们互为邻结点。
起点和终点
在一个有向图中,若存在一条边<vi,vj>, 则称该边是顶点vi的一条出边,
是vj的一条入边,称vi是起始端点(或起点),称vj是终止端
度 图中每个顶点的度是以该顶点为一端点的边的数目。记为 D(V) 。
入度和出度 对于有向图,入度为以该顶点为终点的边的数目,出度为以该顶点为起点的边的目。
点(或终点),并称它们互为邻结点.
子图 :设有两个图G=(V,E) G’=(V’,E’)中,若V’是V的子集, E’是E的子集,则称G’是G子图。
图的存储:(还有许多方法,这些比较简单)
矩阵法:二维数组
邻接法:数组链表
二维数组法简易:
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define MAX 100
typedef struct graph
{
int arcnum;//边数
int vexnum;//顶点数
char vextex[MAX][MAX];//存放多个顶点,顶点用字符串描述
int martrix[MAX][MAX];//权值
}GRAPH,*LPGRAPH;
//行和列定位
int SerrchPos(LPGRAPH g, const char* v)
{
for (int i = 0; i < g->vextex; i++)
{
if (strcmp(g->vextex[i], v) == 0)
{
return i;
}
}
return -1;
}
LPGRAPH CreateGraph()
{
LPGRAPH g = (LPGRAPH)malloc(sizeof(GRAPH));
assert(g);
printf("输入顶点数和边数");
scanf_s("%d%d", &g->arcnum, &g->vexnum);
printf("输入顶点");
for (int i = 0; i < g->vexnum; i++)
{
scanf_s("%s", g->vextex[i], 20);
}
//矩阵的初始化,所有位置置为0
memset(g->martrix, 0, sizeof(int) * 100 * 100);
char v1[20];
char v2[20];//起点和终点
int vrt;//权值
int i = 0;
int j = 0;
printf("输入各条边的信息\n");
for (int k = 0; k < g->arcnum; k++)
{
scanf_s("%s%s%d", v1, 20, v2, 20, &vrt);
//把权值填充到矩阵中,行和列的求解
i = SerrchPos(g, v1);
j = SerrchPos(g, v2);
if(i==-1||j==-1)
{
printf("输入有误,请重新输入");
k--;
continue;
}
g->martrix[i][j] = vrt;
}
printf(".....");
}
//图的输出
void printGraph(LPGRAPH g)
{
for (int i = 0; i < g->vexnum; i++)
{
printf("\t%s", g->vextex[i]);
}
printf("\n");//换行
for (int i = 0; i < g->vexnum; i++)
{
printf("%s\t", g->vextex[i]);//打印顶点
for (int j = 0; j < g->martrix; j++)
{
printf("%d\t", g->martrix[i][j]);
}
printf("\n");
}
}
int main()
{
LPGRAPH g = CreateGraph();
printGraph(g);
return 0;
}