图形结构10.docx

上传人:b****6 文档编号:3626331 上传时间:2022-11-24 格式:DOCX 页数:47 大小:280.43KB
下载 相关 举报
图形结构10.docx_第1页
第1页 / 共47页
图形结构10.docx_第2页
第2页 / 共47页
图形结构10.docx_第3页
第3页 / 共47页
图形结构10.docx_第4页
第4页 / 共47页
图形结构10.docx_第5页
第5页 / 共47页
点击查看更多>>
下载资源
资源描述

图形结构10.docx

《图形结构10.docx》由会员分享,可在线阅读,更多相关《图形结构10.docx(47页珍藏版)》请在冰豆网上搜索。

图形结构10.docx

图形结构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的路径为,而路径的长度为经过的边数,在这个例子中,路径的长度为3。

7.简单路径

所谓简单路径(SimplePath)是指在图中除了起点和终点可以重复(不重复亦可)外,其余的顶点皆不相同的路径。

如上图的为简单路径,而,,,,,不是简单路径,因为在这条路径中顶点1和顶点2重复经过。

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//--------------------

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1