图的定义

概述

(Graph)是一种比线性表和树更为复杂的数据结构

线性结构:是研究数据元素之间的一对一关系。在这种结构中,除第一个和最后一个元素外,任何一个元素都有唯一的一个直接前驱和直接后继。 

树结构:是研究数据元素之间的一对多的关系。在这种结构中,每个元素对下()可以有0个或多个元素相联系,对上()只有唯一的一个元素相关,数据元素之间有明显的层次关系。

图结构:是研究数据元素之间的多对多的关系。在这种结构中,任意两个元素之间可能存在关系。即结点之间的关系可以是任意的,图中任意元素之间都可能相关。

 图的基本概念

  图的定义和术语

一个(G)定义为一个偶对(V,E) ,记为G=(V,E) 。其中: V是顶点(Vertex)的非空有限集合,记为V(G)E是无序集V&V的一个子集,记为E(G) ,其元素是图的弧(Arc)

将顶点集合为空的图称为空图。其形式化定义为:

G=(V ,E)

V={v|vÎdata object}

E={<v,w>| v,wÎVp(v,w)}

P(v,w)表示从顶点v到顶点w有一条直接通路。

(Arc) :表示两个顶点vw之间存在一个关系,用顶点偶对<v,w>表示。通常根据图的顶点偶对将图分为有向图和无向图。

有向图(Digraph) 若图G的关系集合E(G)中,顶点偶对<v,w>vw之间是有序的,称图G是有向图。

在有向图中,若 <v,w>ÎE(G) ,表示从顶点v到顶点w有一条弧。 其中:v称为弧尾(tail)或始点(initial node)w称为弧头(head)或终点(terminal node) 

无向图(Undigraph) 若图G的关系集合E(G)中,顶点偶对<v,w>vw之间是无序的,称图G是无向图。 

在无向图中,若"<v,w>ÎE(G) ,有<w,v>ÎE(G) ,即E(G)是对称,则用无序对(v,w) 表示vw之间的一条边(Edge),因此(v,w) (w,v)代表的是同一条边。

1:设有有向图G1和无向图G2,形式化定义分别是:

G1=(V1 ,E1)

V1={a,b,c,d,e}

E1={<a,b>,<a,c>, <a,e>,<c,d>,<c,e> ,<d,a>,<d,b>,<e,d>}

G2=(V2 ,E2)

V2={a,b,c,d}

E2={(a,b), (a,c), (a,d), (b,d), (b,c), (c,d)}

它们所对应的图如图所示。

完全无向图:对于无向图,若图中顶点数为,用e表示边的数目,则Î[0n(n-1)/2] 。具有n(n-1)/2条边的无向图称为完全无向图。完全无向图另外的定义是:

对于无向图G=(VE),若"vivj Î,当vivj时,有(vi ,vj)ÎE,即图中任意两个不同的顶点间都有一条无向边,这样的无向图称为完全无向图。

完全有向图:对于有向图,若图中顶点数为,用e表示弧的数目,则eÎ[0n(n-1)] 。具有n(n-1)条边的有向图称为完全有向图.完全有向图另外的定义是:

对于有向图G=(VE),若"vivjÎ,当vi vj时,有<vi ,vj>ÎE<vj , vi >Î,即图中任意两个不同的顶点间都有一条弧,这样的有向图称为完全有向图。

有很少边或弧的图(e<nn)的图称为稀疏图,反之称为稠密图

(Weight)与图的边和弧相关的数。权可以表示从一个顶点到另一个顶点的距离或耗费。

子图和生成子图:设有图G=(VE)G=(V’,E),若V’ÌVE’Ì,则称图G’是G的子图;若V=VE’ÌE,则称图G’是G的一个生成子图。

顶点的邻接(Adjacent)对于无向图G=(VE),若边(v,w)ÎE,则称顶点v互为邻接点,即vw相邻接。边(v,w)依附(incident)与顶点v

对于有向图G=(V E),若有向弧<v,w>ÎE,则称顶点“邻接到”顶点w,顶点“邻接自”顶点,弧<v,w> 与顶点v“相关联” 。

顶点的度、入度、出度:对于无向图G=(VE), "viÎV,图G中依附于vi的边的数目称为顶点vi(degree),记为TD(vi)

显然,在无向图中,所有顶点度的和是图中边的2倍。 即   ∑TD(vi)=2e      i=1, 2, , n e为图的边数。

对有向图G=(VE),若"vi Î,图G中以vi作为起点的有向边()的数目称为顶点vi出度(Outdegree),记为OD(vi) ;以vi作为终点的有向边()的数目称为顶点vi入度(Indegree),记为ID(vi) 。顶点vi的出度与入度之和称为vi的度,记为TD(vi) 。即

TD(vi)=OD(vi)+ID(vi) 

路径(Path)、路径长度、回路(Cycle) 对无向图G=(VE),若从顶点vi经过若干条边能到达vj,称顶点vivj是连通的,又称顶点vivj路径

对有向图G=(VE),从顶点vivj有有向路径,指的是从顶点vi经过若干条有向边()能到达vj。或路径是图G中连接两顶点之间所经过的顶点序列。即  

Path=vi0vi1…vim vijÎV(vij-1, vij)ÎE   j=1,2, ,m 或  

Path=vi0vi1 …vim vijÎV<vij-1, vij>ÎE  j=1,2, ,m 

路径上边或有向边()的数目称为该路径的长度

在一条路径中,若没有重复相同的顶点,该路径称为简单路径;第一个顶点和最后一个顶点相同的路径称为回路();在一个回路中,若除第一个与最后一个顶点外,其余顶点不重复出现的回路称为简单回路(简单环)

连通图、图的连通分量:对无向图G=(VE),若"vi vj ÎVvivj都是连通的,则称图G连通图,否则称为非连通图。若G是非连通图,则极大的连通子图称为G连通分量。 

对有向图G=(VE),若"vi vj ÎV,都有以vi为起点, vj 为终点以及以vj为起点,vi为终点的有向路径,称图G是强连通图,否则称为非强连通图。若G是非强连通图,则极大的强连通子图称为G强连通分量。 

“极大”的含义:指的是对子图再增加图G中的其它顶点,子图就不再连通

生成树、生成森林:一个连通图(无向图)的生成树是一个极小连通子图,它含有图中全部n个顶点和只有足以构成一棵树的n-1条边,称为图的生成树,如图所示。

关于无向图的生成树的几个结论:

 ◆ 一棵有n个顶点的生成树有且仅有n-1条边;

 ◆ 如果一个图有n个顶点和小于n-1条边,则是非连通图;

 ◆ 如果多于n-1条边,则一定有环;

 ◆ 有n-1条边的图不一定是生成树。

有向图的生成森林是这样一个子图,由若干棵有向树组成,含有图中全部顶点。

有向树是只有一个顶点的入度为,其余顶点的入度均为1的有向图,如图7-3所示。

网:每个边(或弧)都附加一个权值的图,称为带权图。带权的连通图(包括弱连通的有向图)称为网或网络。网络是工程上常用的一个概念,用来表示一个工程或某种流程,如图7-4所示。

图的抽象数据类型定义

图是一种数据结构,加上一组基本操作就构成了图的抽象数据类型。图的抽象数据类型定义如下:

Graph{

数据对象V:具有相同特性的数据元素的集合,称为顶点集。

数据关系RR={VR}

VR={<v,w>|<v,w>| v,wÎVp(v,w) <v,w>表示从vw的弧,P(v,w)定义了弧<v,w>的信息 }

基本操作P: 

添加顶点

添加边

获得顶点的个数

获得边的条数

移除顶点

移除边

……

}


图的接口Graph

[java]  view plain  copy
  1. package datastructure.graph;  
  2. /** 
  3.  * 图的接口 
  4.  * @author luoweifu 
  5.  * 
  6.  */  
  7. public interface Graph {  
  8.     /** 
  9.      * 添加顶点 
  10.      * @param v 
  11.      */  
  12.     public void addVex(Object v);  
  13.     /** 
  14.      * 添加边 
  15.      * @param v1 第一个顶点 
  16.      * @param v2 第二个顶点 
  17.      * @param weight 权值 
  18.      */  
  19.     public void addEdge(Object v1, Object v2, double weight);  
  20.     /** 
  21.      * 添加边 
  22.     * @param v1 第一个顶点 
  23.      * @param v2 第二个顶点 
  24.      * @param info 边信息 
  25.      * @param weight 权值 
  26.      */  
  27.     public void addEdge(Object v1, Object v2, Object info, double weight);  
  28.     /** 
  29.      * 置空图 
  30.      */  
  31.     public void clear();  
  32.     /** 
  33.      * 获得顶点v的第一个邻接结点 
  34.      * @param v 顶点 
  35.      * @return 顶点v的第一个邻接结点 
  36.      */  
  37.     public Object getFirstVertex(Object v);  
  38.     /** 
  39.      * 在图G中寻找v1结点的邻接结点v2的下一个邻接结点 
  40.      * @param v1 顶点 
  41.      * @param v2 v1的一个邻接结点 
  42.      * @return 邻接v1的在v2后的一个结点 
  43.      */  
  44.     public Object getNextVertex(Object v1, Object v2);  
  45.     /** 
  46.      * 获得顶点的个数 
  47.      * @return 
  48.      */  
  49.     public int getVertexSize();  
  50.     /** 
  51.      *获得边的条数 
  52.      * @return 
  53.      */  
  54.     public int getEdgeSize();  
  55.     /** 
  56.      * 移除顶点 
  57.      * @param v 顶点 
  58.      */  
  59.     public void removeVex(Object v);  
  60.     /** 
  61.      * 移除边 
  62.      * @param v1 顶点1 
  63.      * @param v2 顶点2 
  64.      */  
  65.     public void removeEdge(Object v1, Object v2);  
  66.     /** 
  67.      * 深度优先遍历 
  68.      * @param o 遍历的初始顶点 
  69.      * @return 遍历的结果 
  70.      */  
  71.     public String dfs(Object o);  
  72.     /** 
  73.      * 深度优先遍历 
  74.      * @param o 遍历的初始顶点 
  75.      * @return 遍历的结果 
  76.      */  
  77.     public String bfs(Object o);  
  78.     /** 
  79.      * 打印图的各顶点 
  80.      * @return 
  81.      */  
  82.     public String printGraph();  
  83. }  

边的接口Edge

[java]  view plain  copy
  1. package datastructure.graph;  
  2.   
  3.   
  4. public abstract class Edge implements Comparable{  
  5.     protected double weight;  
  6.     protected Object info;  
  7.     /** 
  8.      * 构造函数 
  9.      */  
  10.     public Edge() {  
  11.         this.weight = 0;  
  12.     }  
  13.     /** 
  14.      * 构造函数 
  15.      * @param weight 权值 
  16.      */  
  17.     public Edge(double weight) {  
  18.         this.weight = weight;  
  19.     }  
  20.     public Edge(Object info, double weight) {  
  21.         this.weight = weight;  
  22.         this.info = info;  
  23.     }  
  24.       
  25.     /** 
  26.      * 获取权值 
  27.      * @return 权值 
  28.      */  
  29.     public double getWeight() {  
  30.         return weight;  
  31.     }  
  32.     /** 
  33.      * 设置权值 
  34.      * @param weight 权值 
  35.      */  
  36.     public void setWeight(double weight) {  
  37.         this.weight = weight;  
  38.     }  
  39.     /** 
  40.      * 获取边的信息 
  41.      * @return 边的信息 
  42.      */  
  43.     public Object getInfo() {  
  44.         return info;  
  45.     }  
  46.     /** 
  47.      * 设置边的信息 
  48.      * @param info 边的信息 
  49.      */  
  50.     public void setInfo(Object info) {  
  51.         this.info = info;  
  52.     }  
  53.     /** 
  54.      * 获取边的第一个顶点 
  55.      * @return 第一个顶点 
  56.      */  
  57.     public abstract Object getFirstVertex();  
  58.     /** 
  59.      * 获取边的第二个顶点 
  60.      * @return 第二个顶点 
  61.      */  
  62.     public abstract Object getSecondVertex();  
  63. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值