图形结构10.docx
- 文档编号:3626331
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:47
- 大小:280.43KB
图形结构10.docx
《图形结构10.docx》由会员分享,可在线阅读,更多相关《图形结构10.docx(47页珍藏版)》请在冰豆网上搜索。
图形结构10
第十章图形结构
10.1图的基本概念
10.2图的存储结构
10.3图的遍历
10.4生成树问题
10.5最短路径问题
图是一种比线性表、二叉树更复杂的数据结构,任意两个数据元素之间都可以有关系。
图的应用非常能够广泛,已渗透到诸如语言学、逻辑学、物理、化学、电讯工程、计算机学科等其他分支中。
10.1图的基本概念
1.图的定义
在图G中包含了两个集合,一个是由顶点(Vertices或nodes)所构成的有限的非空集合,另一个是由边(Edges或Arcs)所构成的有限非空集合,我们用G(V,E)来表示。
2.无向图
一个图G中,如果用一条无序偶代表一条边,则称边是无向的,用圆括号将一对结点括起来表示无向边,此时图G称为无向图。
集合的概念中,我们可以将上图表示为:
V(G)=(1,2,3,4)
E(G)={(1,2),(1,3),(2,3),(2,4),(3,4)}
3.有向图
一个图G中如果用结点的有序偶代表一条边,则称边是有向的,用尖括号将一对结点括起来表示有向边,此时称图G为有向图。
从集合的概念中,我们可以将上图表示为:
V(G)=(1,2,3,4)
E(G)={<1,2>,<1,3>,<1,4>,<2,4>,<3,4>}
4.完全图
一个有n个结点的无向图,其边的最大数目为n*(n-1)/2,若一个图就具有最大值的边数,则该图为完全图。
一个有n个结点的有向图,其边的最大数目为n*(n-1),若一个有向图就具有最大值的边数,则该图为有向完全图。
5.子图
所谓的子图(Sub-Graph)是指由图G中取出的部分集合,如下图为图G
则以下各图皆为其子图形
6.路径
所谓路径(Path)是指在图中从顶点A到达顶点B,经过的所有边。
例如下图从顶点1到顶点5的路径为
7.简单路径
所谓简单路径(SimplePath)是指在图中除了起点和终点可以重复(不重复亦可)外,其余的顶点皆不相同的路径。
如上图的
8.回路
所谓回路(Cycle)是指在图中,起点和终点相同的简单路径。
如下图中,
9.强连通图
如果在有向图中,任意两个顶点间皆存在一条路径可到对方,则称为强连通图(StronglyConnectedGraph)。
10.2图形的表示法
1.数组表示法
数组表示法(AdjacentMatrix)是以一个n*n的数组来表示一个具有n个顶点的图。
我们以数组的下标值来表示顶点,以数组的内容值来表示顶点间的边是否存在(以1表示存在边,以0表示不存在边)。
如下图的无向图形:
其邻接数组为:
01234
在无向图中,邻接数组是一个对称矩阵。
但在有向图中,邻接数组内容不一定对称。
下面用一个程序实例来说明图的数组表示法
1.程序目的
设计一个将图转成邻接数组的程序
2.程序构思
用户输入各个边,再将边转成邻接数组。
3.程序源代码
01//==============ProgramDescription=============
02//程序名称:
mgraph.java
03//程序目的:
设计一个将图形转成邻接数组的程序.
04//WrittenByKuo-YuHuang.(WANTStudio.)
05//======================================
06importConsoleReader.*;//引入已定义的数据输入类
07
08publicclassmgraph
09{
10publicstaticintMax=6;//定义最大可输入数
11//图形邻接数组
12publicstaticintGraph[][]=newint[Max][Max];
13
14publicstaticvoidmain(Stringargs[])
15{
16intSource;//起始顶点
17intDestination;//终止顶点
18inti,j;//循环计数变量
19ConsoleReaderconsole=newConsoleReader(System.in);
20
21for(i=0;i 22for(j=0;j 23Graph[i][j]=0; 24while(true) 25{ 26System.out.print(“PleaseinputtheEdge’ssource(-1forExit): ”); 27Source=console.readInt(); 28if(Source==-1) 29break; 30 31System.out.print(“PleaseinputtheEdge’sDestination: ”); 32Destination=console.readInt(); 33 34//错误: 自身循环 35if(Source==Destination) 36System.out.println(“@Error@: SelfLoop! ! ”); 37//错误: 超出范围 38elseif(Source>=Max||Destination>=Max) 39System.out.println(“@Error@: Outofrange! ! ”); 40else//调用建立邻接数组 41CreateMGraph(SourceDestination); 42} 43System.out.println(“##Graph##”); 44PrintMGraph();//调用输出邻接数组数据 45} 46 47//---------------------------------------------------- 48//输出邻接数组数据 49//---------------------------------------------------- 50publicstaticvoidPrintMGraph() 51{ 52inti,j;//循环计数变量 53 54System.out.print(“Vertice”); 55for(i=0;i 56System.out.print(““+i+”“); 57System.out.println(““); 58 59for(i=0;i 60{ 61System.out.print(““+i+”“); 62for(j=0;j 63System.out.print(““+Graph[i][j]+”“); 64System.out.println(““); 65} 66} 67 68//---------------------------------------------------- 69//以邻接数组建立图 70//---------------------------------------------------- 71publicstaticvoidCreateMGraph(intVerticel,intVertice2) 72{ 73Graph[Vertice1][Vertice2]=1;//将数组内容设为1 74} 75} 2.邻接表表示法 邻接表法(AdjacencyList)是以链表来记录各顶点的邻接顶点。 其结点结构如下: 如下图的有向图: 其邻接表为: 3.多重邻接表表示法 在无向图的邻接表表示法中,每一个边都会出现两次。 在多重邻接表中结点可以在多个列表中使用。 多重邻接表的结点结构如下: 每一个结点记录着一个边的数据。 如下的无向图形: 有5条边E1=(1,2),E2=(1,3),E3=(1,4),E4=(2,4),E5=(3,4)。 其多重邻接表为: 10.3图的遍历 遍历是图的基本操作。 对于一个图,从其中的一个顶点出发,以某种次序顺序的访问图中的每个顶点,并且每个顶点只能被访问一次,这一过程称为图的遍历。 10.3.1深度优先遍历 深度优先遍历类似树的先根遍历。 1.算法描述 在图中,如果以顶点V作为起始点开始搜索,我们从顶点V的邻接表中选择一个未搜索过的顶点W,由顶点W继续进行深度优先法的搜索,每搜索一个顶点,便把该顶点压入堆栈。 直到搜索到已经没有任何邻接的未遍历的顶点U,此时取栈顶顶点,回到上一层顶点继续搜索未遍历的顶点,直到所有的顶点皆搜索过为止。 2.实例 对于下图的无向图形: 操作过程: (1)如果从顶点1开始深度优先搜索,顶点1存入堆栈。 (2)顶点1的邻接顶点为顶点2和顶点3,选择顶点2(也可以选择顶点3)往下继续深度优先搜索,将顶点2存入堆栈。 (3)顶点2的邻接顶点为顶点4和顶点5,选择顶点4往下继续深度优先搜索,将顶点4存入堆栈。 (4)顶点4的邻接顶点为顶点8,将顶点8存入堆栈。 (5)发现顶点8的邻接顶点为顶点4、顶点5、顶点6和顶点7,顶点4已经搜索过,选择顶点5继续深度优先搜索,将顶点5存入堆栈。 5 (6)发现顶点5的邻接顶点为顶点2,顶点2已经搜索过,退回到顶点8,将顶点5从堆栈取出。 (7)发现顶点8的邻接顶点为顶点4、顶点5、顶点6和顶点7,顶点4和顶点5已经搜索过,选择顶点6继续深度优先搜索,将顶点6存入堆栈。 (8)发现顶点6的邻接顶点为顶点3,选择顶点3继续深度优先搜索,将顶点3存入堆栈。 3 (9)发现顶点3的邻接顶点为顶点7,选择顶点7继续深度优先搜索,将顶点7存入堆栈, 7 (10)发现顶点7的邻接顶点皆搜索完,取出堆栈中顶点,堆栈中所有顶点的邻接皆已搜索(此时堆栈为空),结束。 所以搜索的顺序为: 顶点1、顶点2、顶点4、顶点8、顶点5、顶点6、顶点3、顶点7 因为深度优先搜索时,同一深度的邻接顶点,可选择其中一个继续进行邻接顶点的深度搜索,所以深度优先搜索的顺序不是惟一的。 设计深度优先搜索程序时,我们可采用堆栈来存储未搜索的邻接顶点,或者采用递归来调用深度优先搜索函数,搜索未曾搜索过的顶点。 3.程序实现 (1)程序目的 设计一个深度优先搜索法来搜索上述图形的程序 (2)程序构思 递归调用深度优先搜索法 (3)程序源代码 //==========ProgramDescription============ //程序名称: dfs.java //程序目的: 设计一个深度优先搜索法来搜索图形的程序. //WrittenByKuo-YuHuang.(WANTStudio.) //================================= importConsoleReader.*;//引入已定义的数据输入类 publicclassdfs { publicstaticintVertexNum=9; publicstaticint[]Visited=newint[VerexNum];//搜索记录 publicstaticint[][]Node= {{1,2},{2,1},{1,3},{3,1},{2,4}, {4,2},{2,5},{5,2},{3,6},{6,3}, {3,7},{7,3},{4,8},{8,4},{5,8}, {8,5},{6,8},{8,6},{7,8},{8,7}}; //图形邻接数组 publicstaticintGraph[][]=newint[VertexNum][VertexNum]; publicstaticvoidmain(Stringargs[]) { intSource;//起始顶点 intDestination;//终止顶点 inti,j;//循环计数变量 ConsoleReaderconsole=newConsoleReader(System.in); for(i=0;i for(j=0;j Graph[i][j]=0; for(i=0;i<20;i++) { //调用建立邻接数组 CreateMGraph(Node[i][0],Node[i][j]); } System.out.println(“##Graph##”); PrintMGraph();//调用输出邻接数组数据 System.out.println(“Deph-First-Search: ”); System.out.print(“[BEGIN]==>”); DFS (1); System.out.print(“[END]”); } //------------------------------------------------- //深度优先搜索法 //------------------------------------------------- publicstaticvoidDFS(intVertex) { intPointer;//结点声明 inti; Visited[Vertex]=1;//已搜索 System.out.print(“[“+Vertex+”]==>”); for(i=1;i { if(Graph[Vertex][i]==1&&Visited[i]==0) DFS(i);//递归调用 } } //------------------------------------------------- //输出邻接数组数据 //------------------------------------------------- publicstaticvoidPrintMGraph() { inti,j;//循环计数变量 System.out.print(“Vertice”); for(i=0;i System.out.print(““+i+”“); System.out.println(“”); for(i=0;i { System.out.print(““+i+”“); for(j=0;j System.out.print(““+Graph[i][j]+”“); System.out.println(““); } } //------------------------------------------------- //以邻接数组建立图形 //------------------------------------------------- publicstaticvoidCreateMGraph(intVerticel,intVertice2) { Graph[Vertice1][Vertice2]=1;//将数组内容设为1 } } 10.3.2广度优先遍历 广度优先遍历类似于树的按层遍历。 1.算法描述 在图中,如果以顶点V作为起始点开始搜索,我们从顶点V的邻接表中选择一个未搜索过的顶点W,将顶点V的所有邻接顶点搜索过后,再继续对顶点W的所有邻接顶点进行广度优先法的搜索,然后再继续搜索顶点V的下一个邻接顶点的所有邻接顶点,重复进行广度优先搜索,直到所有的邻接顶点皆搜索过为止。 通常是使用队列来存储邻接顶点,每搜索一个邻接顶点便把其所有的邻接顶点存入队列中,直到队列空为止。 2.实例 对于下图的无向图形 广度优先搜索的操作过程如下: (1)如果从顶点4开始广度优先搜索,将顶点4存入队列中。 4 (2)搜索顶点4,将顶点4的邻接顶点存入队列中,将顶点4从队列中取出。 2 (3)搜索顶点2,将顶点2的邻接顶点存入队列中,邻接顶点4已搜索过,不必存入队列中。 将顶点2从队列中取出。 8 (4)搜索顶点8,将顶点8的邻接顶点存入队列中,邻接顶点4已搜索过和邻接顶点5已再队列中,所以不必存入队列,将顶点8从队列中取出。 1 (5)搜索顶点1,将顶点1的邻接顶点存入队列中,邻接顶点2已搜索过,不必存入队列中,将顶点1从队列中取出。 5 (6)搜索顶点5,将顶点5的邻接顶点存入队列中,邻接顶点2和邻接顶点8已搜索过,不必存入队列,将顶点5从队列中取出。 6 (7)搜索顶点6,将顶点6的邻接顶点存入队列中,邻接顶点8已搜索过和邻接顶点3已在队列中,所以不必存入队列,将顶点6从队列中取出。 7 (8)搜索顶点7,将顶点7的邻接顶点存入队列中,邻接顶点8已搜索过和邻接顶点3已在队列中,不必存入队列中,将顶点7从队列中取出。 3 (9)搜索顶点3,顶点3的邻接顶点皆已搜索过,不必存入队列。 将顶点3从队列中取出,此时队列为空,结束搜索。 所以广度优先搜索的顺序为: 顶点4,顶点2,顶点8,顶点1,顶点5,顶点6,顶点7,顶点3 因为广度优先搜索时,一个顶点可以有多个邻接点,选择其中一个继续进行邻接顶点的广度搜索,所以广度优先搜索的顺序也不是惟一的。 3.程序实现 程序源代码 01//==========ProgramDescription============ 02//程序名称: bfs.java 03//程序目的: 设计一个广度优先搜索法来搜索图形的程序. 04//WrittenByKuo-YuHuang.(WANTStudio.) 05//================================= 06importConsoleReader.*;//引入已定义的数据输入类 07 08publicclassbfs 09{ 10publicstaticintVertexNum=9; 11publicstaticint[]Visited=newint[VerexNum];//搜索记录 12publicstaticint[][]Node= 13{{1,2},{2,1},{1,3},{3,1},{2,4}, 14{4,2},{2,5},{5,2},{3,6},{6,3}, 15{3,7},{7,3},{4,8},{8,4},{5,8}, 16{8,5},{6,8},{8,6},{7,8},{8,7}}; 17publicstaticintGraph[][]=newint[VertexNum][VertexNum]; 18 19publicstaticvoidmain(Stringargs[]) 20{ 21intSource;//起始顶点 22intDestination;//终止顶点 23int,j;//循环计数变量 24ConsoleReaderconsole=newConsoleReader(System.in); 25 26for(i=0;i 27for(j=0;j 28Graph[i][j]=0; 29 30for(i=0;i<20;i++) 31{ 32//调用建立邻接数组 33CreateMGraph(Node[i][0],Node[i][1]); 34} 35 36System.out.println(“##Graph##”); 37PrintMGraph();//调用输出邻接数组数据 38 39System.out.println(“Bradth-First-Search: ”); 40System.out.print(“[BEGIN]==>”); 41DFS(4); 42System.out.print(“[END]”); 43} 44 45//--------------------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图形 结构 10