数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
目录
1.图的定义和基本术语
1.图的定义
图G由两个集合V和E组成,记为G=(V,E),其中V是顶点的有穷非空集合,E是V中顶点偶对的有穷集合,这些顶点偶对称为边。V(G)和E(G)通常分别表示图G的非顶点集合和边集合,E(G)可以为空集。若E(G)为空,则图G只有顶点而没有边。
对于图G,若边集E(G)为有向边的集合,则称该图为有向图;若边集E(G)为无向边的集合,则称该图为无向图。
在有向图中,顶点对<x,y>是有序的,它称为与顶点X和顶点y相关联的一条边。因此,<x,y>与<x,y>是不同的两条边。顶点对用尖括号括起来,对<x,y>而言,x是有向边的始点,y是有向边的终点。<x,y>也称作一条弧,则x为弧头,y为弧尾。
在无向图中,顶点对(x,y)是无序的,它称为与顶点x和顶点y相关联的一条边。这条边没有特定的方向,(x,y)与(y,x)是一条边,为了有别于有向图,无向图的顶点对用一对圆括号括起来。
有向图:w'w
无向图:
ww
2.基本术语
(1)子图:假设有两个图,如果后者是前者的子集,则称后者为前者的子图。
(2)无向完全图和有向完全图:对于无向图,若具有m(n-1)/2条边,则成为无向完全图。对于有向图,若具有n(n-1)条弧,则称为有向完全图。
(4)权和网:在实际应用中,每条边可以标上具有某种含义的数值,该数值称为该边上的权值。这些权值可以从一个顶点到另一个顶点的距离或耗费。这种带权的图通常称为网。
(5)邻接点:对于无向图G,如果说图的边有两个相邻的点,则称这两个相邻的点为其的邻接点。或者说这两个点与其相关联。
(6)度、入度和出度:顶点v的度是指和v先关联的边的数目,记为入度和出度。入度是以顶点为头的弧的数目;出度是以顶点为尾的弧的数目。两者之和为总度数。
(7)路径和路径长度:在无向图G中,从顶点V到V‘的路径是一个顶点序列,如果G是有向图,则路径也有是有向的,路径长度是一条路径上经过的边或弧的数目。
(8)回路和环:第一个顶点和最后一个顶点相同的路径称为回路或环。
(9)简单路径,简单回路或简单环:序列中顶点不重复出现的路径称为简单路径。除了第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路,称为简单回路或简单环。’
(10)连通、连通图和联通分量:在无向图G中,如果从顶点V到顶点V‘有路径,则称V和V’是联通的。如果对于图中任意两个顶点都是连通的,则称G是连通图;所谓连通分量,指的是无向图中的极大连通子图。
(11)强连通图和强连通分量:在有向图G中,如果对于每一对顶点都存在路径,则称G是强连通图,但它有连个强连通分量。
(12)连通图的生成树:一个极小连通子图,它含有图中全部顶点,但只有足以构成一棵树的n-1条边,这样的连通子图称为连通图的生成树。如果在一棵生成树上添加一条边,必定构成一个环,因为这条边使得它依附的那个顶点之间有了第二条路径。
一棵有n个顶点的生成树有且仅有n-1条边。如果一个图有n个顶点和小于n-1条边,则是非连通图。如果它多于n-1条边,则一定有环。但是,有n-1条边的图不一定是生成树。
(13)有向树和生成森林:有一个顶点的入度为0,其中顶点的入度均为1的有向图称为有向树。一个有向图的生成森林是由若干棵有向树组成,含有图中全部顶点,但只有足以构成若干棵不相交的有向树的弧。
2.图的类型定义
关于图的类型概念比较笼统,这里我们选择用邻接矩阵的存储结构来讲解图的基本结构及类型定义,关于邻接矩阵的相关知识点将会在后面的文章介绍。代码段选用C#讲解。
首先是替换符部分,为了更好的迎合教材以及讲解代码的形式,我们选择用大量替换符来替换基础术语:
#include <stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
#define MaxInt 32767 //表示极大值,即∞
#define MVNum 100 //最大顶点数
typedef int VerTexType;//假设顶点的数据类型为整型
typedef int ArcType; //假设边的权值类型为整型
然后是建立图的基本结构体,因为是选用邻接矩阵。所以包含顶点表,邻接矩阵以及点数和边数
typedef struct
{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的当前点数和边数
}AMGraph;
然后是查询位置的函数,因为在输入图的基本信息时会需要查找下标,所以事先定义查询下标函数
Status LocateVex(AMGraph *G,VerTexType v) //查询顶点v在图G中的下标位置
{
for(int i=0;i<G->vexnum;i++){
if(G->vexs[i]==v){
return i;
}
}
}
再然后就是无向图的创建与输入,因为是邻接矩阵所以套用两个for循环,一个用来输入节点信息,一个创造边来连接各邻接点。
//此处定义无向图的创建
Status CreateUDG(AMGraph *G){
scanf("%d %d",&G->vexnum,&G->arcnum);//输入总顶点数,总边数
for(int i=0;i<G->vexnum;i++){
scanf("%d",&G->vexs[i]);//输入点的信息
}
int v1,v2;
int m,n;
for(int j=0;j<G->arcnum;j++){
scanf("%d %d",&v1,&v2);//输入一条边依附的顶点
int m=LocateVex(G,v1);
int n=LocateVex(G,v2);
G->arcs[m][n]=1;
G->arcs[n][m]=1;
}
return OK;
}
之后就是图的输出模块,输出方式很普通,不做 过多赘述
Status PrintAMGraph(AMGraph *G){
for(int i=0;i<G->vexnum;i++){
for(int j=0;j<G->vexnum;j++){
printf("%d",G->arcs[i][j]);
printf(" ");
}
printf("\n");
}
return OK;
}
以上就为图的基本结构,但也仅仅是基本结构,关于图的存储结构由多种,这里只是选用相对好理解的邻接矩阵进行举例说明,具体的存储结构还要再后面进行详细讲解。
3.小总结
本次内容主要了讲解了数据结构中的一些基础知识点,主要内容顺序表的有关知识本篇内容都为数据结构的基本思想,若想更深的理解以及体会,还请大家在日常学习中多多努力,希望大家学有所成。以下附上本段讲解代码
#include <stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
#define MaxInt 32767 //表示极大值,即∞
#define MVNum 100 //最大顶点数
typedef int VerTexType;//假设顶点的数据类型为整型
typedef int ArcType; //假设边的权值类型为整型
typedef struct
{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的当前点数和边数
}AMGraph;
Status LocateVex(AMGraph *G,VerTexType v) //查询顶点v在图G中的下标位置
{
for(int i=0;i<G->vexnum;i++){
if(G->vexs[i]==v){
return i;
}
}
}
//此处定义无向图的创建
Status CreateUDG(AMGraph *G){
scanf("%d %d",&G->vexnum,&G->arcnum);//输入总顶点数,总边数
for(int i=0;i<G->vexnum;i++){
scanf("%d",&G->vexs[i]);//输入点的信息
}
int v1,v2;
int m,n;
for(int j=0;j<G->arcnum;j++){
scanf("%d %d",&v1,&v2);//输入一条边依附的顶点
int m=LocateVex(G,v1);
int n=LocateVex(G,v2);
G->arcs[m][n]=1;
G->arcs[n][m]=1;
}
return OK;
}
//此处定义无向图的邻接矩阵的输出
Status PrintAMGraph(AMGraph *G){
for(int i=0;i<G->vexnum;i++){
for(int j=0;j<G->vexnum;j++){
printf("%d",G->arcs[i][j]);
printf(" ");
}
printf("\n");
}
return OK;
}
int main()
{
AMGraph *G;
G=(AMGraph *)malloc(sizeof(100*4));
//调用利用邻接矩阵创建无向图的函数CreateUDG
CreateUDG(G);
//调用输出邻接矩阵的函数PrintAMGraph
PrintAMGraph(G);
return 0;
}