1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题...

481

Click here to load reader

description

1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径. 第七章 图. 7.1 图的定义和术语. 无向图 G 2. 有向图 G 1. A. B. A. B. E. C. D. C. D. 结点(顶点). 结点(顶点). A. B. A. B. 有向边(弧)、弧尾(初始结点)、弧头(终止结点). 边(无向边). A. B. A. B. 有向图: G 2 =(V 2 ,E 2 ) V 2 = {A,B,C,D,E} - PowerPoint PPT Presentation

Transcript of 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题...

Page 1: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、图的定义和术语2 、图的存储结构3 、图的遍历4 、图的连通性问题5 、有向无环图及其应用6 、最短路径

第七章 图

Page 2: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7.1 图的定义和术语

A B

C D

A B

C D

E

有向图 G1

无向图 G2

结点 ( 顶点 )

有向边(弧)、弧尾 ( 初始结点 ) 、弧头 ( 终止结点 )

A B

A B

有向图: G1=(V1, E1)

V1 = {A,B,C,D}

E1 = {<A,B>, <A,C>,

<C,D>, <D,A>}

结点 ( 顶点 )

边 ( 无向边 )

A B

有向图: G2=(V2, E2)

V2 = {A,B,C,D,E}

E2 = {(A,B), (A,C),(B,D),

(B,E) , (C,E),(D,E)}

A B

Page 3: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

A B

C D

无向图 G2

A B

C D

A

C

A B

C D

有向图 G1 的子图

A B

C D

E

A B

D

E

A A B

C D

A B

C D

E

无向图 G2 的子图

有向图 G1

Page 4: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

无向图的连通性

A B

C D

E

路径:在无向图 G=(V,E) 中由顶点 v 至 v’ 的顶点序列。回路或环:第一个顶点和最后一个顶点相同的路径。简单回路或简单环:除第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路。连通:顶点 v 至 v’ 之间有路径存在连通图:无向图图 G 的任意两点之间都是连通的,则称 G 是连通图。连通分量:极大连通子图

F G

I J

L

H

M

K

A B

C D

E

H

M

F G

I J

LK

无向图 G 无向图 G 的三个连通分量

Page 5: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

有向图的连通性

路径:在有向图 G=(V,E) 中由顶点 v 经有向边至 v’ 的顶点序列。回路或环:第一个顶点和最后一个顶点相同的路径。

简单回路或简单环:除第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路。连通:顶点 v 至 v’ 之间有路径存在

强连通图:有向图 G 的任意两点之间都是连通的,则称 G 是强连通图。强连通分量:极大连通子图

有向图 G 有向图 G 的两个强连通分量

A B

C D

A B

C D

Page 6: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

生成树:极小连通子图。包含图的所有 n 个结点,但只含图的 n-1 条边。在生成树中添加一条边之后,必定会形成回路或环。

A B

C D

E

H

M

A B

C D

E

H

M

无向图 G 无向图 G 的生成

Page 7: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

完 全 图:有 n(n-1)/2 条边的无向图。其中 n 是结点个数。

有向完全图:有 n(n-1) 条边的有向图。其中 n 是结点个数。

边的权值 : 边有权的图称之为网。

邻接点:

无向图结点的度

有向图结点的出度和入度

A B

C D

E

H

M

无向图 G1

图的其它术语

有向图 G2

A B

C D

Page 8: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

图的常用存储形式:•邻接矩阵和加权邻接矩阵•邻接表

1 、邻接矩阵和加权邻接矩阵( labeled adjacency matrix)

A B

C D

无权值的有向图的邻接矩阵 设有向图有 n 个结点,则用 n 行 n 列矩阵 A 表示有向图; 如果 i至 j 有一条弧,则 A[i,j] =1 ;否则, A[i,j]=0

注意: A[i,i]=0。

出度 : i 行之和;入度 : j 列之和。

表示成右图矩阵

0 1 1 0

0 0 0 0

0 0 0 1

1 0 0 0

7.2 图的存储结构

Page 9: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

无权值的无向图的邻接矩阵

设无向图有 n 个结点,则用 n 行 n 列的矩阵 A 表示该无向图;

如果 i至 j 有一条边 ,则 A[i,j]=1 ; 否则, A[i,j]=0

注意: A[i,i ]= 0。

i 结点的度 : i 行或 i 列之和。

为对称矩阵。

表示成右图矩阵

0 1 1 0 0

1 0 0 1 1

1 0 0 0 1

0 1 0 0 1

0 1 1 1 0

A B

C D

E

Page 10: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

图的加权邻接矩阵

设图有 n 个顶点,则用 n 行 n 列的矩阵 A 表示该图;

如果 i至 j 有一条边(弧)且它的权值为 w 。则 A[i,j]=w ; 否则, A[i,j]= ∞ (或其它标志);

a

b表示成右图矩阵

∞ a b ∞

∞ ∞ ∞ b

∞ ∞ ∞ b

a ∞ a ∞

1 2

3 4

a

a b

b

Page 11: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

图的建立:图顶点号从 1 开始计,数组下标按 C/C++ 习惯从 0 计算

#define MAXINT (1<<sizeof(int)*8-1)-1 CreateGraph(a[][VexNuM],e) // VexNuM- 图的顶点数 ,e- 边(弧)数 { for(i=0;i<VexNuM;i++) for(j=0;j<VexNuM;j++) a[i][j]= MAXINT; for(k=1;k<=e;k++) { cin>>I>>j>>w;// 读入顶点号 i,j 和边上权 w a[i-1][j-1]=w; a[j-1][i-1]=w;// 无向图 } }

Page 12: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、邻接表

设图具有 n 个结点,则用顶点数组表、边(弧)表表示该有向图或无向图。

顶点数组表:用数组存放所有的顶点。数组大小为图顶点数 n。

边表(边结点表):每条边用一个结点进行表示。同一个结点的所有的边形成它的边结点单链表。

数组顶点表中的分量的形式:

data: 结点的数据域,保存结点的数据值(比如顶点号)。

firstarc: 结点的指针域,给出自该顶点出发的的第一条边(弧)的边结点的地址。

VNode:

data firstarc

Page 13: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

边表中的结点的形式

adjvex: 结点的数据域,保存结点的数据(比如顶点号)。

nextvex: 结点的指针域,给出该结点的下一结点(边)的地址。info: 边结点的数据域,保存边的 权值等。如不是网,此部分可省去。

ArcNode: adjvex nextarc info

Page 14: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

实例:

无向图 G2

1 2

3 4

5

1 2

3 4

有向图 G1 adj

0123

2 ^1

34

2 3 ^

1 ^

4 ^

adj

01234

21

345

2

11 4 5 ^

2 3

5 ^

5 ^

2 3 ^

5 ^

Page 15: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

逆邻接表——对有向图而言

1 2

3 4

有向图 G1

0123

21

34

4 3 ^

3 ^

1 ^

adj

1 ^

Page 16: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

有向图邻接表建立

思考:若为无向图? 逆邻接表作业:有向图中( 1 )增加一条弧 Addarc(adj,u,v)

(2) 删除一条弧 Delarc(adj,u,v)

void Create(adj,n,e) //adj :邻接表表头数组, n 个顶点 ,e 条弧{ for(i=0;i<n;i++) { adj[i].data=i+1; adj[i].firstarc=NULL;} for(i=1;i<=e;i++) { cin>>u>>v;// 输入一条弧 <u,v> p =new ArcNode; p->adjvex=v; p->nextarc=adj[u-1].firstarc; adj[u-1].firstarc=p; }}

Page 17: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7.3 图的遍历

图的二种常见的遍历形式:•深度优先搜索•广度优先搜索

1 、深度优先( DFS )搜索访问方式:从图中某顶点 v 出发: 1 )访问顶点 v;2 )从 v 的未被访问的邻接点出发,继续对图进行深度优先遍历,若从某点出发所有邻接点都已访问过,退回前一个点继续上述过程,若退回开始点,结束。

遍历:图中顶点访问一次且仅一次。 因为一个顶点可以和其它的任何顶点相邻接,为了避免对一个顶点的重复访问,必须对访问过的顶点加以标记。由于顶点的邻接次序是任意的,因此遍历可能有多种可能。

Page 18: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 26 57 43

搜索的实现(设图是连通的)1 、设置一个栈 A )图上任选一个点入栈,并访问 B )若栈空,转 C), 否则 从栈顶结点出发,选尚未访问的结点访问并进栈 若已无这样的点,则退栈 C )结束

5 6 7

2

4

1

3

8

8

11

3

6

3

1

6

3

1

8

7

6

3

1

8

6

3

1

8

6

3

1

8

5

1

2

6

3

1

8

5

2

6

3

1

8

5

4

2

6

3

1

8

5

6

3

1

8

5

6

3

1

8

6

3

1栈空3

1

Page 19: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

使用的变量说明: visited[VNUM] ;// 用于标识结点是否已被访问过 VNUM代表图的顶点数,访问过置 1 (初始所有 visited[i] 为 0 )

void DFS(G,v)// 从图 G 的顶点 v 开始搜索{ visited[v]=1; cout<<v<<endl; for(w=FirstAdjVex(G, v) ; w!=NULL ; w=NextAdjVex(G,v w)) if( !Visited[w]) DFS(G,w);}

此算法处理抽象的图 G ,当图为邻接表时,则可细化为:

Page 20: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

adj

123456

87

01234 5 6 7

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

dfs(adj,1)

Page 21: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

Page 22: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

Page 23: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

Page 24: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

Page 25: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

Page 26: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

Page 27: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

Page 28: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

Page 29: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

Page 30: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

Page 31: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

Page 32: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

Page 33: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

Page 34: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

Page 35: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

Page 36: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

Page 37: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

dfs(adj,5)

Page 38: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

dfs(adj,5)

Page 39: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

dfs(adj,5)

5

Page 40: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

dfs(adj,5)

5

Page 41: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

dfs(adj,5)

5

Page 42: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8

dfs(adj,5)

5

Page 43: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

Page 44: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

Page 45: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

Page 46: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

Page 47: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6

Page 48: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6

Page 49: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)

Page 50: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)

Page 51: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

Page 52: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

Page 53: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

Page 54: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

Page 55: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

dfs(adj,7)

Page 56: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

dfs(adj,7)

Page 57: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

dfs(adj,7)

7

Page 58: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

dfs(adj,7)

7

Page 59: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

dfs(adj,7)

7

Page 60: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3

dfs(adj,7)

7

Page 61: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3 7

Page 62: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 dfs(adj,3)3 7

Page 63: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 3 7

Page 64: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 3 7

Page 65: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5

dfs(adj,6)

6 3 7

Page 66: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5 6 3 7

Page 67: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5 6 3 7

Page 68: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4

dfs(adj,8)

8 5 6 3 7

Page 69: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4 8 5 6 3 7

Page 70: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2

dfs(adj,4)

4 8 5 6 3 7

Page 71: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2 4 8 5 6 3 7

Page 72: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1

dfs(adj,2)

2 4 8 5 6 3 7

Page 73: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1 2 4 8 5 6 3 7

Page 74: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1 2 4 8 5 6 3 7

Page 75: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1 2 4 8 5 6 3 7

Page 76: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void dfs(adj,v){ visited[v-1]=1; cout<<v; for(p=adj[v-1].firstarc;p!=NULL;p=p->next) if(visited[p->adjvex-1]==0) dfs(adj,p->adjvex);}

5 6 7

2

4

1

3

8

123456

87

01234 5 6 7

adj

2 8

51 4

2 8

2 3

3 83 8

71 6

75 64

dfs(adj,1)

1 2 4 8 5 6 3 7

Page 77: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、广度(宽度, BFS )优先搜索1 )访问顶点 v ;

2 )访问同 v 相邻的所有未被访问的邻接点 w1,w2, …

wk;

3 )依次从这些邻接点出发,访问它们的所有未被访问的邻接点 ; 依此类推,直到图中所有访问过的顶点的邻接点都被访问;

Page 78: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

图的广度优先的访问次序:

1 、 2 、 11 、 12 、 3 、 6 、 7、 10 、 4 、 5、 8、 9

适用的数据结构:队列

12

1

2 11

3 6 7 10

4 5 8 9

1

2 1211

3 6 7 10

4 5 8 9

Page 79: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void BFS( G, v){ 初始化队列 Q; visited[u]=1; cout<<u; EnQueue(Q,v);//v 进队 while (队 Q 不空 ) { DeQueue(Q,u);// 队头元素放在 u 中,退队 visited[u]=1; cout<<u; for ( w = FirstAdjVex(G, u) ; w ; w = NextAdjVex(G, u, w)) if ( visited[ w ]==0 ) {// w 进队

visited[u]=1; cout<<u;EnQueue(Q, w) ; } //if

} //while}

12

1

2 11

3 6 7 10

4 5 8 9

1 2 12 11

12 11 3 6

11 3 6

3 6 7 10

6 7 10 4

7 10 4 5

10 4 5 8

4 5 8 9

Page 80: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

前面的遍历算法实际上求出的是一个连通分量,利用它们可遍历图(以 DFS 为例子)

void trave(G){for(v=0;v<VNUM;v++) visited[v]=0;for(v=0;v<VNUM;v++) if(visited[v]= =0) DFS(G,v);}

Page 81: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 、遍历应用举例

1) 求一条从顶点 i 到顶点 s

的 简单路径2) 求两个顶点之间的一条路径 长度最短的路径

Page 82: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1) 求一条从顶点 i 到顶点 s 的简单路径

a

b

c

h

d e

k

f

g 求从顶点 b 到顶点 k 的一条简单路径。 从顶点 b 出发进行深度优先搜索遍历。

例如 :

假设找到的第一个邻接点是 a,则得到的结点访问序列为 : b a d h c e k f g 。

假设找到的第一个邻接点是 c,则得到的结点访问序列为 : b c h d a e k f g ,

Page 83: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

(1) 从顶点 i 到顶点 s ,若存在路径,则从顶点 i 出发进行深度优先搜索,必能搜索到顶点 s。(2) 遍历过程中搜索到的顶点不一定是路径上的顶点。

(3) 由某点出发进行的深度优先遍历经过若干点后,若又回退到该点,则中间完成的顶点( s 不在其中)不是路径上的顶点。

结论 :

Page 84: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2) 求两个顶点之间的一条路径 长度最短的路径

若两个顶点之间存在多条路径,则其中必有一条路径长度最短的路径。如何求得这条路径 ?

Page 85: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ab

c

hd

ek

fg

因此,求路径长度最短的路径可以基于广度优先搜索遍历进行,但需要在新进队时,记住前一个出队的点。若进队的是目的点,则从开始点到该点记录的序列为最短路径。

深度优先搜索访问顶点的次序取决于图的存储结构,而广度优先搜索访问顶点的次序是按“路径长度”渐增的次序。

Page 86: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g

队头

Page 87: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g

队头

路径:b->cb->ab->g

Page 88: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h

队头

路径:b->cb->ab->g

Page 89: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h

队头

路径:b->c->hb->ab->g

Page 90: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h

队头

路径:b->c->hb->ab->g

Page 91: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e

队头

路径:b->c->hb->ab->g

Page 92: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e

队头

路径:b->c->h

b->g

Page 93: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e

队头

路径:b->c->h

b->g

b->a->db->a->fb->a->e

Page 94: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e

队头

路径:b->c->h

b->g

b->a->db->a->fb->a->e

Page 95: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e

队头

路径:b->c->h

b->g

b->a->db->a->fb->a->e

Page 96: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e

队头

路径:b->c->h

b->g

b->a->db->a->fb->a->e

Page 97: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e

队头

路径:b->c->h

b->g

b->a->db->a->fb->a->e

Page 98: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e->k

队头

路径:b->c->h

b->g

b->a->db->a->fb->a->e

Page 99: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e->k

队头

路径:b->c->h

b->g

b->a->db->a->f->kb->a->e

Page 100: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ca

b

hd

ek

fg

ab

c

hd

ek

fg

b->c->a->g->h->d->f->e->k

队头

路径:b->c->h

b->g

b->a->db->a->f->kb->a->e

Page 101: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7.4 生成树和最小生成树一、生成树 每次遍历一个连通图将图的边分成遍历所经过的边和没有经过的边两部分,将遍历经过的边同图的顶点构成一个子图,该子图称为生成树。因此有 DFS 生成树和 BFS 生成树。

5 6 7

2

4

1

3

8

生成树是连通图的极小子图,有 n个顶点的连通图的生成树必定有 n-1 条边 , 在生成树中任意增加一条边,必定产生回路。

Page 102: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

二、最小代价生成树(简称:最小生成树)1.定义:生成树中边的权值(代价)之和最小的树。

实例:

1

2 43

5 6

6 1

6

5

5 5

63 4 2

1

2 43

5 6

1

5

3 4 2

左图的最小代价生成树

Page 103: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

MST 性质:

假设 G={V,E} 是一个连通图, U 是结点集合V 的一个非空子集。若(u,v) 是一条代价最小的边,且 u 属于 U,v属于 V - U, 则必存在一棵包括边 (u,v) 在内的最小代价生成树。

证明:假定存在一棵不包括边 (u,v) 在内的最小代价生成树,设其为T 。将边 (u,v) 添加到树 T, 则形成一条包含 (u v) 的回路。因此,必定存在另一条边 (u’, v’),且 u’属于 U ,v’属于 V - U 。删去边(u’,v’) ,得到另一棵生成树 T’; 因为边 (u,v) 的代价小于边 ( u’, v’)的代价,所以新的生成树 T’将是代价最小的树 , 和原假设矛盾。

u

u’ v’

v

T

UV

Page 104: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2. 求最小生成树的原则 ( 1 )选取 n-1 条边连通图 ( 2 )尽量选取边权小的边

令最小生成树集合T初始状态为空,在有 n 个顶点的图中选取代价最小的边并从图中删去。若该边加到T中有回路则丢弃,否则留在 T中;依此类推,直至 T中有 n-1 条边为止。

3. Kruskal 算法

Page 105: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1

65

4

3

2

6 5

1

3

5

6

6

42

5

1

3

1

6

4

2

5

2

3 4

5

实现时主要解决回路判定问题

5

Page 106: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4.Prim 算法 设图顶点数为 n 。

设置一个集合U ,开始图上任选一点 u0 加入 U

重复以下工作 n-1 次

a) 在满足 uU,vU 的所有边中选边权w 最小的

b) 将 v 加入集合U 中

c) 输出边 u ,v 及边上的权 w

5

3

6

6

1

1

2 43

5 6

5

5

6 4 2

1

2 43

5 6

1

5

3 4 2

Page 107: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

Prim 算法实现 1 :( 1 )集合:设置一个数组 set[i](i=0,1,..,n-1), 初始值为 0,代表对应顶点不在集合中(注意:顶点号与下标号差 1 )( 2 )图用邻接阵表示,路径不通用无穷大表示,在计算机中可用一个大整数代替。#define MAXINT (1<<(sizeof(int)*8-1) )-1void prim1(g,v0,n)//g- 图, v0-起始点( 1到 n),n- 图顶点数{ for(i=0;i<n;v++) set[i]=0; //memset(set,’\0’,sizeof(set)) set[v0-1]=1; for(k=1;k<=n-1;k++){ min=MAXINT; for(i=0;i<n;i++) if(set[i]==1) for(j=0;j<n;j++) if(set[j]==0 ) if(g[i][j]<min) { p=i;q=j;min=q[i][j];} set[q]=1; cout<<p+1<<‘ ‘<<q+1<<‘ ‘<<min<<endl; }//for k}

时间: O( n3)

n-1 次循环步骤 a

步骤 b

步骤 c

Page 108: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

Prim 算法实现 2 :A. 图的一个子图作为一个集合 U ,定义顶点 i到集合的距离( iU)

lowcost[i]=min{ g[k,i]| kU,iU}

∞ 若无这样的 k 存在

g 是图的邻接阵lowcost:

1 2 3 4 5 6

3∞7

为了能描述在最短距离时同集合中哪个顶点相邻,增加一个 vex ,标明相邻的顶点号。

vex:

1 2 3 4 5 6

2∞3

3

1 2 45

6

34

17

U3

Page 109: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

lowcost:1 2 3 4 5 6

3∞7

vex:

1 2 3 4 5 6

2∞3

+

lowcost vex

1 2 3 4 5 6

3∞7

2∞3

closedge:

3

1 2 45

6

34

17

U3

重复以下工作 n-1 次

a) 在满足 uU,vU 的所有边中选边权w最小的

b) 将 v 加入集合 Set 中

c) 输出边 u ,v 及边上的权 w

a) 在满足 vU 中选距离

最短的。

(min{closedge[i].lowcost

| i U})b) 将 v 加入集合 Set中

c) 输出边 u ,v 及边上的权 wd)v 加入集合U 后,可能引起与顶点 v 相邻结点的 lowcos和 vex的修改

3∞7

2∞3

1 2 3 4 5 6

Page 110: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

lowcost:1 2 3 4 5 6

3∞7

vex:

1 2 3 4 5 6

2∞3

+

lowcost vex

1 2 3 4 5 6

3∞7

2∞3

closedge:

3

1 2 45

6

34

17

U3

重复以下工作 n-1 次

a) 在满足 uU,vU 的所有边中选边权w最小的

b) 将 v 加入集合 Set 中

c) 输出边 u ,v 及边上的权 w

a) 在满足 vU 中选距离

最短的。

(min{closedge[i].lowcost

| i U})b) 将 v 加入集合 Set中

c) 输出边 u ,v 及边上的权 wd)v 加入集合U 后,可能引起与顶点 v 相邻结点的 lowcos和 vex的修改

3∞7

2∞3

1 2 3 4 5 6

Page 111: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

lowcost:1 2 3 4 5 6

3∞7

vex:

1 2 3 4 5 6

2∞3

+

lowcost vex

1 2 3 4 5 6

3∞7

2∞3

closedge:

3

1 2 45

6

34

17

U3

重复以下工作 n-1 次

a) 在满足 uU,vU 的所有边中选边权w最小的

b) 将 v 加入集合 Set 中

c) 输出边 u ,v 及边上的权 w

a) 在满足 vU 中选距离

最短的。

(min{closedge[i].lowcost

| i U})b) 将 v 加入集合 Set中

c) 输出边 u ,v 及边上的权 wd)v 加入集合U 后,可能引起与顶点 v 相邻结点的 lowcos和 vex的修改

337

243

1 2 3 4 5 6

Page 112: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

lowcost:

1 2 3 4 56

3∞7

vex:

1 2 3 4 5 6

2∞3

+

lowcost vex

1 2 3 4 5 6

3∞7

2∞3

closedge:

3

1 2 45

6

34

17

U3

重复以下工作 n-1 次

a) 在满足 uU,vU 的所有边中选边权w最小的

b) 将 v 加入集合 Set 中

c) 输出边 u ,v 及边上的权 w

a) 在满足 vU 中选距离

最短的。

(min{closedge[i].lowcost

| i U})b) 将 v 加入集合 Set中

c) 输出边 u ,v 及边上的权 wd)v 加入集合U 后,可能引起与顶点 v 相邻结点的 lowcost和 vex的修改

331

244

1 2 3 4 5 6

Page 113: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void Prim2(gn[][NUM],v0)//gn: 图的邻接阵, NUM :图的顶点数, v0 :起始点( 1到n) for(v=0;v<=NUM;v++) set[v]=0;for(v=0;v<NUM;v++) if(v!=v0){ closedge[v].vex=v0; closedge[v].lowcost=gn[v0-1][v];}//closedge 初始化set[v0-1]=1;for(i=0;i<NUM-1;i++){{ wmin=MAXINT; for(v=0;v<NUM;v++) if(set[v]==0 && closedge[v].lowcost<wmin) { k=v; wmin=closedge[v].lowcost;} cout<<k+1<<‘ ‘<<closedge[k].vex<<‘ ‘; cout<<closedge[k].lowcost; set[k]=1; for(v=0;v<NUM;v++) if(set[v]==0 && gn[k][v]<closedge[v].lowcost) {closedge[v].lowcost=gn[k][v]; closedge[v].vex=k; } }//for i}

当顶点放入集合 set 后, lowcost就无用了,因此,省去set,利用 lowcost 实现。

closedge[v0-1].lowcost=0; set[v]==0改为:closedge[v].lowcost>0

set[v]==0改为:closedge[v].lowcost>0

实际上,只有在closedge[v].lowcost>0时才可能有: gn[k][v]<closedge[v].lowcost( 因为若 v属于 U ,对应的lowcost 为 0 ),所以,可省去 closedge[v].lowcost>0 的判定

时间: O(n2)

Page 114: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

C1

C2

C3

C4 C5

C6

C7

C8

C9 C10

C11

C12

7.5 有向无环图及应用7.5 .1 拓扑排序

课程代号 课程名称 先修课C1 程序设计基础 无C2 离散数学 C1

C3 数据结构 C1,C2

C4 语言的设计和分析 C1

C5 计算机原理 C3,C4

C6 程序设计基础 C11

C7 编译原理 C3, C5

C8 操作系统 C3,C6

C9 高等数学 无C10 线性代数 C9

C11 普通物理 C9

C12 数值分析 C1,C9,C10

Page 115: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

5 重(双)连通图和关节点

问题: 若从一个连通图中删去任何一个顶点及其相关联的边,它仍为一个连通图的话,则该连通图被称为重(双)连通图。

Page 116: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

若连通图中的某个顶点和其相关联的边被删去之后,该连通图被分割成两个或两个以上的连通分量,则称此顶点为关节点。没有关节点的连通图为双连通图。

如何判别给定的连通图是否是双连通图?

Page 117: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

a

h g

c

b f

d e

例如 :下列连通图中 :

Page 118: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

a

h g

c

b f

d e

例如 :下列连通图中 :(去除 a)

h g

c

b f

d e

Page 119: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

a

h g

c

b f

d e

例如 :下列连通图中 :(去除 c)

a

h g

b f

d e

Page 120: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

a

h g

c

b f

d e

例如 :下列连通图中 :

所以:顶点 a 和顶点 c 是关节点

Page 121: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

关节点有何特征?

假设从某个顶点 V0 出发对连通图进行深度优先搜索遍历,则可得到一棵深度优先生成树,树上包含图的所有顶点。

需借助图的深度优先生成树来分析。

Page 122: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

a

h g

c

b f

d e

a

b

c

d

e

f

g

h

例如 :下列连通图中: 深度优先生成树(从 a 开始)

Page 123: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

若生成树的根结点,有两个或两个以上的分支,则此顶点 ( 生成树的根 )

必为关节点;

对生成树上的任意一个非叶“顶点”,若其某棵子树中的所有“顶点”没有和其祖先相通的回边,则该“顶点”必为关节点。

Page 124: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

a

h g

c

b f

d e

a

b

c

d

e

f

g

h

例如 :下列连通图中: 深度优先生成树(从 a 开始)

Page 125: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

对上述两个判定准则在算法中如何实现?

Page 126: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

定义函数 :

low(v) = min{visited[v], low[w], visited[k] }

其中 : 顶点 w 是生成树上顶点 v 的孩子; 顶点 k 是生成树上和顶点 v 由回边相联接的祖先

(包含和双亲的连接,此处也称回边); visited 记录深度优先遍历时的访问次序

w

v

a b

u

5

4

3

2 1(low)low(w)=1

Page 127: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

a

b

c

d

e

f

g

h

1

2

3

4

5

6

7

8

3

3 1

1

1

1

1

1

深度优先生成树若对顶点 v ,在生成树上存在一个子树根 w ,

且 low[w] ≥ visited[v]

则顶点 v 为关节点。

Page 128: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径
Page 129: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1、 AOV- 网 用顶点表示活动,边表示活动的优先关系的有向图称为AOV 网。

若 <vi,vj> 是图中有向边,则 vi是 vj 的直接前驱; vj是 vi

的直接后继。若存在一条从 vi到 vj 的路径,则称 vi是 vj 的前驱, vj是 vi 的后继。AOV 网中不允许有回路,这意味着某项活动以自己为先决条件。

3 、拓扑排序:对 AOV 网络中顶点构造拓扑有序序列的过程。

2 、拓扑有序序列: 把 AOV 网络中各顶点按照它们相互之间的优先关系排列一个线性序列的过程。若 vi是 vj 前驱,则 vi 一定在 vj 之前;对于没有优先关系的点,顺序任意。

Page 130: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v4

v2

v6

v3

v5

v1

Page 131: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v4

v2

v6

v3

v5

Page 132: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v4

v2

v6

v3

v5

v5

Page 133: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v4

v2

v6

v3

v5

Page 134: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v4

v2

v6

v3

v5 v4

Page 135: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v2

v6

v3

v5 v4

Page 136: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v2

v6

v3

v5 v4 v3

Page 137: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v2

v6

v5 v4 v3

Page 138: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v2

v6

v5 v4 v3 v2

Page 139: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v6

v5 v4 v3 v2

Page 140: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1

v6

v5 v4 v3 v2 v6

Page 141: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 、拓扑排序的方法(1) 在有向图中选一个没有前驱的顶点且输出之(2) 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止 ( 此时说明图中有环)

v1 v5 v4 v3 v2 v6

拓扑排序的结果不是唯一的

Page 142: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

v4

v2

v6

v3

v5

v1

v1

Page 143: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

v4

v2

v6

v3

v5

v1

Page 144: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

v4

v2

v6

v3

v5

v1 v3

Page 145: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

v4

v2

v6v5

v1 v3

Page 146: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

v4

v2

v6v5

v1 v3 v2

Page 147: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

v4

v6v5

v1 v3 v2

此时已找不到无前驱的顶点,说明有回路。

Page 148: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

5.拓扑排序算法实现 为了能方便的找到结点后继,用邻接表表示图,增加一个数组indegree 存对应结点的入度,这样查无前驱的结点转化为查入度为 0 的结点。

0 2 2 031indegree:

对应的结点号: 1 2 3 4 5 6

1 2

34

56

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

Page 149: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

算法描述:( 1 )把邻接表中入度为 0 的顶点依此进栈( 2 )若栈不空,则 a) 栈顶元素 vj 退栈并输出; b) 在邻接表中查找 vj 的直接后继 vk ,把 vk 的入度减 1 ;若 vk 的入度为 0 则进栈 若栈空时输出的顶点个数不是 n ,则有向图有环;否则,拓扑排序完毕。

Page 150: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 2 031indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

05

Page 151: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 2 031indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

Page 152: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 2 031indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

栈6

Page 153: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 2 031indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

栈6

Page 154: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 2 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

栈6

Page 155: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 2 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

栈6

Page 156: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 1 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

栈6

Page 157: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 1 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

栈6

Page 158: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 1 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

0

栈6

Page 159: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 1 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6

Page 160: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 1 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

Page 161: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 1 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

Page 162: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 0 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

Page 163: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 0 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

Page 164: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 0 021indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

Page 165: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

Page 166: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

32

Page 167: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 2 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

32

Page 168: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

32

Page 169: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

32

Page 170: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

32

Page 171: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

Page 172: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

Page 173: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 020indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

Page 174: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

Page 175: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 1 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

Page 176: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

Page 177: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

1

Page 178: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

1

Page 179: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

1

Page 180: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3

Page 181: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3 2

Page 182: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3 2

Page 183: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1

3

3 2

Page 184: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2

Page 185: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4

Page 186: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 010indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4

Page 187: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4

Page 188: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4

4

Page 189: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4

4

Page 190: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4

4

Page 191: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4

Page 192: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4 5

Page 193: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4 5

Page 194: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

NUM: 图顶点数, adj :邻接表表头void topsort(adj){ 初始化栈 ; findindegree(adj,indegree); for(i=0;i<NUM;i++) if(indegree[i]==0) push(i); count=0; while( 栈不空) { i=pop(); cout<<i+1; count++; for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; indegree[k]--; if(indegree[k]==0) push(k); } } if(count<NUM) cout<<“ 有回路” <<endl;}

0 0 0 000indegree:1 2 3 4 5 6

5 2 ^

5 ^

5 4 ^4

65

102 ^132435 ^

34 2 ^adj

栈6 1 3 2 4 5

Page 195: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void findindegree(adj,indegree) { for(i=0;i<NUM;i++) indegree[i]=0; for(i=0;i<NUM;i++) { p=adj[i].firstarc; while(p!=NULL) { k=p->adjvex-1; indegree[k]++; p=p->nextarc; } //while }//for i}

时间分析: O(n+e)

Page 196: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7.5.2 关键路径

2.术语源点:表示整个工程的开始点(入度为 0 )。汇点:表示整个工程的结束点(出度为 0 )。活动(有向边):它的权值定义为 活动进行所需要的时间。方向表示事件的优先关系。

1.AOE 网 (Activity On Edge)——带权的有向无环图,其中顶点表示事件,弧表示活动,权表示活动持续时间。在工程上常用来表示工程进度计划。

Page 197: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

关键活动:活动余量为 0 的活动

关键路径:从源点到汇点的最长的一条路径,或者全部由关键活动构成的路径。

事件的最早发生时间( ve(j)):从源点到 j 结点的最长的路径。意味着事件最早能够发生的时间。

事件的最迟发生时间( vl(j)):不影响工程的如期完工,事件 j 必须发生的时间。

活动 ai 由弧 <j,k> 表示,持续时间记为 dut<j,k>, 则有 :

j kai

dut<j,k>

活动的最早开始时间: e(i)=ve(j)

活动的最迟开始时间: l(i)=vl(k) - dut(<j , k >)

活动余量: l(i)-e(i) 的差 如何求 ve(j)和 vl(j)?

Page 198: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

ve(j)和 vl(j) 的求法:(1)从 ve(1)=0 开始向汇点递推

njTji

jidutiveMaxjvei

2,,

)},()({ )(

其中, T 是所有以 j 顶点为头的弧的集合

i1

i2 j

im6

7

4

105

9

Page 199: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

(2)从 vl(n)=ve(n) 开始向源点递推(汇点的最早开始时间与最迟时间是 一致的)

j1

j2i

jm

20

15

189

10

7

11,,

)},()({ )(

niSji

jidutjvlMinivlj

其中, S 是所有以 i 顶点为尾的弧的集合

Page 200: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

求关键路径例子

9

8

7

64

5

3

2

1 a2 =4

a3 =5

a 5=1

a6=2 a 9=4

a 1=6 a

4 =1 a 7=9

a8=7

a10=2

a 11=4

V1

V2

V3

V4

V5

V6

V7

V8

V9

顶点 Ve Vl064577161418

0668710161418

a1

a2

a3

a4

a5

a6

a7

a8

a9

a10

a11

活动 e l l-e

0 0 00 2 2

6 6 04 6 25 8 37 7 07 7 07 10 316 16 014 14 0

0 3 3

Page 201: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

关键路径算法

4. 利用拓扑排序算法求事件结点的最早发生时间5. 利用逆向拓扑排序算法求事件结点的最迟发生时间

1.建立图的邻接表和逆邻接表2. 利用邻接表求顶点的入度3. 利用逆邻接表求顶点的出度

算法描述:( 1 )把(逆)邻接表中(出)入度为 0 的顶点依此进栈( 2 )若栈不空,则 a) 栈顶元素 vj 退栈并输出; b) 在(逆)邻接表中查找 vj 的直接(前驱)后继 vk ,把vk

的(出)入度减 1 ;若 vk 的(出)入度为 0 则进栈c) ve[k]=max{ve[k],ve[j]+dut<j,k>} 注:对邻接表求 ve,拓扑排序前 ve[i]=0(i=1,2,..,n)

vl[k]=min{vl[k],vl[k]-dut<i,k>)}注:对逆邻接表求 vl, 逆拓扑排序前 vl[i]=ve[n] (i=1,2,..,n-1)

Page 202: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

根据前面算法描述:可以利用前面拓扑排序算法,对邻接表操作就是拓扑排序,对逆邻接表操作就是逆拓扑排序;算法中需增加的是 c )部分。 邻接表和逆邻接表的边结点都增加一个 dut 域,存弧上的权。

C++ 的描述:#define NUM 图顶点数void main(){ Vnode adj[NUM],adj1[NUM]; int ve[NUM],vl[NUM],degree[NUM] // 建立邻接表和逆邻接表表头数组 CreateTable(adj,NUM); CreateTable1(adj1,NUM);// 分别建立邻接表和逆邻接表 TopSort(adj,NUM,ve,0,degree); TopSort(adj1,NUM,vl,ve[NUM-1],degree); PrintEge(adj,NUM,ve,vl);}

Page 203: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void topsort(adj[ ],n,v[ ],x,degree[ ]){ findindegree(adj,degree); for(i=0;i<n;i++) v[i]=x;// 初始化 ve或 vl for(i=0;i<NUM;i++) if(degree[i]==0) push(i); while( 栈不空) { i=pop(); for(p=adj[i].firstarc;p!=NULL;p=p->next) { k=p->adjvex-1; degree[k]--; if(degree[k]==0) push(k); if(x==0) { if(v[i]+p->dut>v[k]) v[k]=v[i]+p->dut;} //求 ve else { if(v[i]-p->dut<v[k]) v[k]=v[i]-p->dut; } //求 vl } //for k }//while}//topsort

Page 204: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void PrintEdg(adj[ ],n,ve[ ],vl[ ]){ for(i=0;i<n;i++) { p=adj[i].firstarc; while(p!=NULL)

{ k=p->adjvex; e=ve[i];

l=vl[k-1]-p->dut; cout<<i+1<<‘ ‘<<k<<‘ ‘<<e<<‘ ‘<<l; if(e= =l) cout<<“ *”;

cout<<endl; p=p->nextrac; }//while }//for}

Page 205: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

α

ω

A

JH

I

G

F

EC

D

B

K6

8

101

6

3

4

3

1

2

7

12

6

10

5

11

8

6

4

4

9 9

3

21

作业:列出下面 AOE- 网的关键路径

Page 206: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7.6.1 从某个源点到其余各顶点的最短路径(单源最短路径问题)

7.6 最短路径

1.问题的提出 用带权的有向图表示一个交通运输网,图中: 顶点——表示城市 边——表示城市间的交通联系 权——表示此线路的长度或沿此线路运输所花的时间或费用等 问题:从某顶点出发,沿图的边到达另一顶点所经过的路径中, 各边上权值之和最小的一条路径——最短路径2. 迪杰斯特拉 (Dijkstra) 算法思想 按路径长度递增次序产生最短路径

3. 所需的辅助数组 dist dist[i](i=1,..n) 存放当前从源点 V0到顶点 i 的最短路径长度,其初态为弧 <v0,i> 上的权值,若该弧不存在,则为无穷大。

Page 207: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4.算法实现分析 设一个集合U ,存放以产生的最短路径的顶点。初始, U 只包含源点 v0 第一条路: 1到 2 、

5 、 3 , 6 之一。取 dist[i] 最小,为 3,3加到U 中第二条路: 1到 2 、 5 、8、 6 之一。而且, 3加到U 中后,某些顶点的 dist 值应调整。

51

2

36

4

57

4

9

20

3

15

8139

3

序号 1 2 3 4 5 6 7 8dist 值 5 4 ∞ 9 2

0 ∞ ∞

7 13

如果下一条最短路径到达顶点 x, 则从源点到 x 的中间点必定都在 U 中反证法:若不成立,则至少有一个中间点 u不属于 U ,如左图vo

u

xU则必定有 dist[u]+dut<u,x>>dist[x] ,按算法,较短路径应已产生,即u 属于 U

Page 208: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

6. Dijkstra 算法描述图用邻接矩阵表示,设置集合 U与辅助数组dist,源点 vo 图的顶点数为 n。g[i,j]代表 <i,j> 上的权;<i,j> 不存在, g[i,j]就为无穷大。(1) dist[i]= g[v0,i] i=1,2,….,n(2) U=[v0];(3) 下面步骤重复 n-1 次 a) 选择 v 使得满足 dist[v]=min{ dist[u]|uU} b) v 加到集合 U 中 U=U{v} c) 修改不在集合 U 中顶点的 dist 值 dist[w]=min{dist[w],dist[v]+g[v,w]|wU}

6

2

7

5

4

3

18

5

6 2

30

13

7

17

32

9

17

2

6

5

79

3230813

g

dist1 2 3 4 5 6 7 13 8 30 32

dist1 2 3 4 5 6 7 13 8 13 30 32

dist1 2 3 4 5 6 7 13 8 13 30 22 20

dist1 2 3 4 5 6 7 13 8 13 19 22 20

dist1 2 3 4 5 6 7 13 8 13 19 21 20

dist1 2 3 4 5 6 7 13 8 13 19 21 20

Page 209: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7. Dijkstra 算法的 C 语言描述 由于 C/C++ 的下标从 0 开始,所以算法中作相应的改动,用 NUM代表图的顶点数

#define NUM void shortpath_dij(g[][NUM],v0) //v0 为源点,值为 1到 NUM{ for(i=0;i<NUM;i++){ set[i]=0; dist[i]=g[v0-1][i];} set[v0-1]=1; for(i=1;i<NUM;i++) { min=MAXINT; for(w=0;w<NUM;w++) if(set[w]= =0 && dist[w]<min) { v=w; min=dist[w]; } set[v]=1; for(w=0;w<NUM;w++) if(set[w]= =0 && dist[v]+g[v][w]<dist[w]) dist[w]=dist[v]+g[v][w]; }//for i} //shortpath_dij

时间分析: O( n2)

Page 210: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

8. 说明 1 )算法仅仅给出了最短路径,没有给出路径的走法。 方案一:用一个二维阵矩,阵矩的第 i 行给出了经过的顶点的集合 , 例如:

0 1 0 1 0 1 1 0 1

……………...

……………..

1 2 3 4 5 6 7 8 9

path=

表示:从源点到顶点 3 经过了顶点 2 、 4 、 6 、 7 、 9

3 行 此方法当在 i,j,k互通时 , 无法反映i->j>k 还是 i->k->j

方案二:给出走图的顺序。(实验实现)

2 )图改用邻接表表示,重写算法。(实验实现)

Page 211: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7.6.2 每一对不同顶点之间的最短路径一、利用 Dijkstra 算法,每次选一个不同的源点 for(i=1;i<=NUM;i++) shotpath_dij(g,i); 时间: O( n3)

二、 Floyed递推算法 以图的邻接矩阵 g 为基础递推: 开始 d0=g, 然后,得到 d1,d2,..dn;即: d0[i,j]=g[i,j]; d(k)[i,j]=min{ d(k-1)[i,j],d(k-1) [i,k]+d(k-1) [k,j]} 1<=k<=n

含义: d(k) 表示从 i到中间点 j, 序号不大于 k 的最短路径长度d0[i,j]代表 i到 j 的路径长度,若存在为弧上权,否则为无穷大。

d1[i,j]= min{ d 0[i,j],d0[i,1]+d0[1,j]} 的意义是:在 i->j 和 i->1,1->j 的两种走法中,选更短的。也就是在允许通过中间点 1的条件下的最短路径。

Page 212: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

依次类推:d2[i,j]= min{ d 1[i,j],d1[i,2]+d1[2,j]} 的意义是:在允许通过中间点 2 的条件下的最短路径。当求到 dn时,在允许通过所有点的条件下的最短路径 ---每对不同顶点之间的最短路径。

时间: d0[i,j]=g[i,j]; d(k)[i,j]=min{ d(k-1)[i,j],d(k-1) [i,k]+d(k-1) [k,j]} 1<=k<=n

O(n3)void floyd(g[][NUM]) { for(v=0;v<NUM;v++) for(w=0;w<NUM;w++) d[v][w]=g[v][w]; for(u=0;u<NUM;u++) for(v=0;v<NUM;v++) for(w=0;w<NUM;w++) if(d[v][w]>d[v][u]+d[u][w]) d[v][w]=d[v][u]+d[u][v]; }

Page 213: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、静态查找表

2 、动态查找表

3 、哈希查找表

第八章 查找

Page 214: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

术语: 查找 (检索 )——根据给定的某个值,在表中确定一个关键字等于给定值的记录或数据元素

关键字——是记录某个数据项的值,它可以 唯一标识 一个记录。

次关键字——不能唯一的确定一个记录,但能确定表的一个子表。子表的元素个数应远少于表中元素数。

为简化问题,将表中元素看成简单的整型数据,理解为关键字部分。

Page 215: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

8.1 静态查找表 1 、顺序表的顺序查找

应用范围:顺序表或线性链表表示的表,表内元素之间无序。 查找过程:从表的一端开始逐个进行记录的关键字和给定值的比较。

search(st,key, n)

// 在有 n 个数据的表 st 中找 key { i=n-1; while(i>=0 && st[i]!=key) i- -; if(i<0) return -1; //查找不成功返回 -1 else return i; //查找成功返回下标号 }

算法主要时间在循环,为减少判定, n 个数据用容量为 n+1的一维数组表示。 st[1]到 st[n] 存储数据, st[0] 作为监视哨

search1(st,key, n) { st[0]=key; i=n; while(st[i]!=key) i- -; return i; //查找返回序号, 0 为不成功 }

Page 216: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

顺序查找的平均时间为表长的一半。2 、顺序有序表的查找——— 二分(折半)查找

查找过程:每次将待查记录所在区间缩小一半适用条件:采用顺序存储结构的有序表算法实现

设表长为 n, low、 high和mid 分别指向待查元素所在区间的上界、下界和中点 ,k 为给定的待查值初始时,令 low=1,high=n,mid=(low+high)/2让 k与mid 指向的记录比较:若 k=r[mid] ,查找成功,结束若 k<r[mid] ,则 high=mid-1若 k>r[mid] ,则 low=mid+1

重复上述操作,直至 low>high时,查找失败highmidlow

Page 217: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

bin_search(st[],key,n) { low=0; hight=n-1; mid=(low+high)/2; while(low<=high) if( st[mid] = = key) return mid; else if(st[mid]>key) high=mid-1; else low=mid+1; return -1; }

mid=(low+high)>>1;

递归:bin_search(st[],key,l,h) { if(l<=h) { mid=(l+h)>>1; if( st[mid] = = key) return mid; else if(st[mid]>key) return bin_search(st,key,l,h-1); else return bin_search(st,key,l+1,h) } else return -1; }

平均查找时间 1)1(log1)1(log1

22

nnn

n

Page 218: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 、分块查找

数据组织: 将表分成几块,块内无序,块间有序;先确定待查记录

所在块,再在块内查找 ( 1 )用数组存放待查记录 ,

( 2 )建立索引表,由每块中最大(小)的关键字及所属块位置的信息组成。

Page 219: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1822 12 13 8 9 20 33 42 44 38 24 48 60 58 74 57 86 53

22 48 86

1 7 13

索引表查 38

•当索引表较大时,可以采用二分查找•在数据量极大时,索引可能很多,可考虑建立索引表的索引,即二级索引,原则上索引不超过三级

Page 220: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分块查找方法评价

2)1(log)2(

1)(2

1

2

1

2

111)1(

2

11

s

s

nASL

ss

nsbi

sj

bASL

sbn

L

L

LLASL

bs

s

i

b

jbs

w

b

wbbs

:用折半查找确定所在块

:用顺序查找确定所在块

查找概率相等,则:记录的个记录,并设表中每个块,每块含的表平均分成若将表长为

均查找长度—在块中查找元素的平—

块的平均查找长度—查找索引表确定所在—其中:

由上面的公式,在 n 一定时,可以通过选择 s使 ASL尽可能小可以证明,当 时,对于( 1) ASL 最小。ns

Page 221: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

小结: 时间:顺序查找最差,二分最好,分块介于两者之间 空间:分块最大,需要增加索引数据的空间 特点: 1 )顺序查找对表没有特殊要求 2 )分块时数据块之间在物理上可不连续。所以可以达到插入、删除数据只涉及对应的块;另外,增加了索引的维护。 3 )二分查找要求表有序,所以若表的元素的插入与删除很频繁,维持表有序的工作量极大。 4 )在表不大时,一般直接使用顺序查找。

Page 222: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

二分查找的 C/C++ 接口

stdlib.h

void *bsearch(void *key,void *base,int nelement,int size, int (*fcmp)(const void *,const void *))

其中: fcmp规定: 第一个数据小于第二个,返回小于 0 的数 第一个数据等于第二个,返回 0 第一个数据大于第二个,返回大于 0 的数

Page 223: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

#include <iostream.h>#include <stdlib.h>cmp(const void *a, const void *b){

if(*(int *)a<*(int *)b) return -1;else if(*(int *)a==*(int *)b) return 0;else return 1; }

void main(){

int ar[]={-2,3,6,9,10,21,22,34,56};int *p;int t;t=9;p=(int *)bsearch(&t,ar,sizeof(ar)/sizeof(int),sizeof(int), cmp);if(p!=NULL) cout<<*p<<endl;

}

Page 224: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

8.2 动态查找

8. 2.1 二叉排序树和二叉平衡树一、二叉排序树

1 二叉排序树定义二叉排序树( Binary Sort Tree )或者是一棵空树;或者是具有下列性质的二叉树:( 1 )若左子树不空,则左子树上所有结点的值均小于它的根结点的值;( 2 )若右子树不空,则右子树上所有结点的值均大于它的根结点的值;( 3 )左、右子树也分别为二叉排序树;

Page 225: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

45

37

24

53

10061

90

78

3

12

根据二叉排序树的定义,对二叉树进行LDR 遍历得到是递增序列。

Page 226: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、查找:

步骤:若根结点的关键字值等于查找的关键字,成功。

否则,若小于根结点的关键字值,递归查左子树。

若大于根结点的关键字值,递归查右子树。

若子树为空,查找不成功。122

250

300110 200

99

105 230

216

TreeNode *SearchBST (t,key )

/* 在二叉分类树查找关键字之值为 key 的结点,找到返回该结点的地址,否则返回空。 t 为二叉分类树的根结点的指针。 */

{ if(t= =NULL||key= =t->data) return t;

else if( key<t->data)

return SearchBST(t->lchild,key);

else return SearchBST(t->rchild,key);

} // SearchBST

Page 227: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 、插入算法:• 首先执行查找算法,找出被插结点的父亲结点。• 判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入。• 若二叉树为空。则首先单独生成根结点。 注意:新插入的结点总是叶子结点。

例:将序列: 122 、 99、 250 、 110 、 300 、 280 作为二叉排序树的结点的关键字值,生成二叉排序树。

122

99 250

300

280

110

Page 228: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void InsertBST(t, key)

// 在二叉排序树中插入查找关键字 key

{

if(t==NULL){

t=new BiTree;

t->lchild=t->rchild=NULL;

t->data=key;

return; }

if(key<t->data ) InsertBST(t->lchild,key);

else InsertBST (t->rchild, key );

}

void CreateBiTree(tree,d[ ],n)//n 个数据在数组 d 中, tree 为二叉排序树根 { tree=NULL;

for(i=0;i<n;i++)

InsertBST(tree,d[i]);

}

类 C 程序实现:

Page 229: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4.二叉排序树中一个结点的删除 在二叉排序树中删除结点的原则是:删除结点后仍是二叉排序树。

设在二叉排序树被删除结点是 x ,其双亲结点为 f 。

情况讨论: ( 1) x 为叶子结点,则直接删除

( 2) x 只有左子树 xL 或只有右子树 xR , 则令 xL或 xR直接成为双亲结点 f 的子树;

ff

x

xL

f

x

xR

f

Page 230: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

( 3) x 即有左子树 xL 也有右子树 xR

f

x

xRxL

在 xL 中选值最大的代替 x ,该数据按二叉排序树的性质应在最右边。

q

f

x

xR

c

s

cL

qLsL

f

s

xR

c

qcL

qL sL

Page 231: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

二叉排序树的删除操作例子

叶子结点:直接删除。如:删除数据为 15 、 70 的结点。

15

60

7030

20

50

60

30

20

50

Page 232: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

122

250

300110 200

99

105 230

216

400

450

500

若被删结点的左儿子为空或者右儿子为空。

如下图所示,删除结点的数据场为 200 的结点。

删除 200 122

250

300230

216

400

450

500

110

99

105

Page 233: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

被删结点的左、右子树皆不空

122

250

300110 200

99

105 230

216

400

450

500

110

250

300105 200

99

230

216

400

450

500

Page 234: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

Page 235: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

p

q

Page 236: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

p

q

Page 237: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

p

q

Page 238: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

p

q

Page 239: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

p

q

s

Page 240: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

p

s

q

Page 241: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

p

sd

q

Page 242: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

d

p

sd

q

Page 243: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

d

p

sd

q

Page 244: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void delete(p) { if(p->rchild = = NULL) { q=p; p=p->lchild; delete q; } else if(p->lchild= =NULL) { q=p; p=p->rchild; delete q; } else { q=p; s=p->lchild; while(s->rchild!=NULL) {q=s; s=s->rchild;} p->data=s->data; if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild; } delete s;}

sp

x

q

p 等于 q 的情况

sp

x

q

Page 245: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

D

A

B

C

F

E

G

二、平衡二叉树

起因:提高查找速度,避免最坏情况出现。如下图单枝情况的出现。

平衡因子(平衡度):结点的平衡因子是结点的左子树的高度减去右子树的高度。(或反之定义)

平衡二叉树:每个结点的平衡因子都为 1 、- 1 、 0 的二叉树。或者说每个结点的左右子树的高度最多差 1 的二叉树。

1 、概念与定义

Page 246: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

0

例:

14

125

3

9 28

6353

60

50

17

18

7 30

1

1

-1

-1

-1

0

0000

0

0 0

平衡二叉树

28

18

14

5

3

9

6353

60

50

17 30

1

2

-1

-1

000

0

1

-1

非平衡二叉树

Page 247: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、平衡树的平衡方法:

在左图所示的平衡树中插入数据为 2 的结点。

插入之后仍应保持平衡分类二叉树的性质不变。

14

125

3

9 28

6353

60

50

17

18

7 30

1

1

-1

-1

-1

0

0000

0

0 0

平衡树

14

125

3

9 28

6353

60

50

17

18

7 30

1 -1

-1

0

0

0000

0

0 0

2

1

1

2

原平衡度为 0

不平衡点

解决:如何用最简单、最有效的办法保持平衡分类二叉树的性质

2

Page 248: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

14

125

3

9 28

6353

60

50

17

18

7 30

+1

+1

-1

-1

-1

0

0000

0

0 0

2

1

1

2

原平衡度为 0

不平衡点

Adelson解决思路:•不涉及到不平衡点的双亲,即以不平衡点为根的子树的高度应保持不变。•新结点插入后,向根回溯找到第一个原平衡因子不为 0 的结点(如图中 9)。新插入的结点和第一个平衡因子不为 0 的结点之间的结点,其平衡因子原皆为 0•在调整中,仅涉及前面所提到的最小子树(如:以 9为根的子树)•仍应保持排序二叉树的性质不变。

Page 249: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 、平衡种类分析 左调整(新结点插入在左子树上的调整):

1、 LL 情况:(插入在结点左子树的左子树上)

LL 旋转

旋转前后:高度都为 h + 1

1

h-1

0A

B

1

h-1

2

h

h-1

BR

AR

BL

B

A

0

h

0

h-1

h-1

BR AR

BL

Page 250: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2、 LR 情况:(新插入结点在左子树的右子树上)

h-1

旋转前后高度仍然是 h + 1

h-1

C

B

0

h-1

BL AR

A

CRh-2CLh-

1

-10

BL

A

B

1

h-1

0

2

-1

AR

AR

C

CRCLh-2

h -1

01 LR旋转

Page 251: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

右调整(新结点插入在右子树上进行的调整)

1、 RR 情况:(插入在的右子树的右子树上)

处理方法和 LL 对称

2、 RL 情况:(插入在右子树的左子树上)

处理方法与 LR 对称

平衡树建立方法:( 1 )按二叉排序树插入结点( 2 )如引起结点平衡因子变为 |2| ,则确定旋转点,该点是离根最远(或最接近于叶子的点)( 3 )确定平衡类型后进行平衡处理,平衡后以平衡点为根的子树高不变

Page 252: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

作业:已知如下所示长度为 12 的表(Jan,Feb,Mar,Apr,May,June,July,Aug,Sep,Oct,Nov,Dec)按所给顺序以字典序( 1 ) 构造二叉排序树;

( 2 )构造二叉平衡树

Page 253: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

采用 B_ 树和 B+ 树目的 应文件系统的要求而发展起来的,大量数据存放在外存中,通常存放在硬盘中。由于是海量数据,不可能一次调入内存。因此,要多次 访问外存。但硬盘的驱动受机械运动的制约,速度慢。所以,主要矛盾变为减少访外存次数。 在 1970 年由 R .bayer 和 E .macreight 提出用B- 树作为索引组织文件。提高访问速度、减少时间。

8.2.2 B- 树和 B+ 树

一、 B- 树及其操作

Page 254: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1、m 阶 B- 树定义:

m 阶 B- 树满足或空,或为满足下列性质的m 叉树:

(1) 树中每个结点最多有 m 棵子树

(2) 根结点在不是叶子时,至少有两棵子树

(3) 除根外,所有非终端结点至少有 m/2棵子树

(4) 有 s 个子树的非叶结点具有 n=s -1 个关键字,结点的信息组织为 :(n,A0,K1,A1,K2,A2 … Kn, An)

这里: n:关键字的个数, ki( i=1,2,…,n) 为关键字,且满足 Ki<Ki+1,, Ai(i=0,1,..n) 为指向子树的指针。

(5) 所有的叶子结点都出现在同一层上,不带信息(可认为外部结点或失败结点)。

Page 255: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

例: 4阶 B- 树。除根结点和叶子结点之外,每个结点的子树个数至少为 m/2 = 2 个;结点的关键字个数至少为 1 。该 B- 树的深度为 4 。叶子结点都在第 4层上。

蓝色代表结点中关键字个数

黑色代表结点中关键字

第 1层

第 2层

第 3层

第 4层

1 33

1 18 2 43 78

1 11 1 27 1 39 1 993 47 58 64

F F F F F F F F FFF F

Page 256: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3、 B- 树的查找:

查找过程,类似于二叉树的查找,关键字为 key 的记录。

从根开始在结点中顺序或二分(当 m 较大时)查找,如果 Ki = key 则查找成功 ,

若 Ki<key<Ki+1 :顺 Ai 指向的子树重复查找

若 key<K1 :顺 A0 指向的子树重复查找

若 key>Kn; :找顺 An 指向的子树重复查找

若找到叶子,则查找失败。

Page 257: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4、 B- 树中结点的插入 m代表 B- 树的阶,插入总发生在最低层 1 ) 插入后关键字个数小于等于 m-1, 完成。

2 ) 插入后关键字个数等于 m, 结点分裂,以中点数据为界一 分为二,中点数据放到双亲结点中。这样就有可能使得 双亲结点的数据个数为 m,引起双亲结点的分裂,最坏情况下一直波及到根,引起根的分裂—— B- 树长高。

12

24 30

45 70

53 90

26 10039 50 61 85

例: 3 阶 B- 树的插入操作。最多 3棵子树, 2 个数据;最少 2棵子树, 1 个数据。

所以 3阶 B- 树也称为 2-3 树。插入位置

插入数据 : 3

3

Page 258: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 12

24 30

45 70

53 90

26 10039 50 61 85

7 24 30

3

45 70

53 90

26 10039 50 61 8512

30

3

24 45 70

53 90

26 10039 50 61 8512

7

100

30

3

24

53 90

26 39 50 61 8512

7

45

70

7插入

7

Page 259: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

5、 B- 树中结点的删除* 删除发生在最底层( 1 )被删关键字所在结点中的关键字数目大于等于 m/2 ,直接删除。( 2 ) 删除后结点中数据为 m/2 -1 ,而相邻的左(右)兄弟中数据大于 m/2 -1 ,此时左(右兄弟)中最大(小)的数据上移到双亲中,双亲中接(靠)在它后 (前)面的数据移到被删数据的结点中。

3

24

45

53 90

37 10050 61 70

被删关键字

3

24

45

61 90

37 10053 70

Page 260: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

(3) 其左右兄弟结点中数据都是 m/2 -1 ,此时和左(右)兄弟合 并,合并时连同双亲中相关的关键字。此时,双亲中少了一项,因此又可能引起双亲的合并,最坏一直到根,使 B- 树降低一层。

3 24

45 90

10061 703

24

45

90

37 10061 70

删除 37

3 24

45

90

10061 70

Page 261: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

* 删除不在最底层 在大于被删数据中选最小的代替被删数据,按 B- 树性质,其位置如下图所示( x 是要删除的数据)

x

y

用于代替 x 的数据

问题转换成在最底层的删除

Page 262: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

作业:试从空树开始,画出按以下次序向 2-3 树中插入数据的建树过程: 20 , 30 , 50 , 52 , 60 , 68 , 70 。如果以后删除50 和 68 ,画出每一步执行后 2-3 树的状态。

20 20 30 30

20 50

30

20 50 52

30 52

20 6050

30 52

20 60 6850

20 6050 70

30 68

5252 68

20 30 7060

52

20 30 60 70

Page 263: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

二、 B+ 树

在实际的文件系统中,用的是 B+ 树或其变形。有关性质与操作类似与 B- 树。1 、差异:( 1 )有 n棵子树的结点中有 n 个关键字( 2 )所有叶子结点中包含全部关键字信息及对应记录位置信息( 3 )所有非叶子为索引,只含关键字而且仅有子树中最大或最小的信息。( 4 )非叶最底层顺序联结,这样可以进行顺序查找

Page 264: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

59 97

15 44 59

10 15

010203060910

对应 01 的记录

Page 265: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2.查找过程※在 B+ 树上,既可以进行缩小范围的查 找,也可以进行顺序查找;※ 在进行缩小范围的查找时,不管成功与否,都必须查到叶子结点才能结束;※若在结点内查找时,给定值≤ Ki , 则应继续在 Ai 所指子树中进行查找

3.插入和删除的操作类似于 B- 树进行,即必要时,也需要进行结点的“分裂”或“合并”。

Page 266: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

8.3 哈希表 前面查找方法共同特点:通过将关键字值与给定值比较,来确定位置。效率取决比较次数。

理想的方法是:不需要比较,根据给定值能直接定位记录的存储位置。这样,需要在记录的存储位置与该记录的关键字之间建立一种确定的对应关系,使每个记录的关键与一个存储位置相对应。

例 1949-2000年某地区人口统计表

可以按公式确定其人数: y年人数 = 表 [y-1948]

年份人数

1 2 3 ….. 51 521949 1950 1951 ……... 1999 20002000 2100 2200 ……... 4400 4420

Page 267: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1.哈希(也称为 Hash 、杂凑、散列)基本思想 在记录的存储地址和它的 关键字之间建立一个确定的对应关系;这样,不经过比较,一次存取就能得到元素。 哈希函数——在记录的关键字与记录的存储位置之间建立的一种对应关系。 哈希函数是一种映象,是从关键字空间到存储位置空间的一种映象。哈希函数可写成: addr(ai)=h(ki)

ai 是表中的一个元素addr(ai)是 ai 的存储位置信息ki是 ai 的关键字

Page 268: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

哈希表——应用哈希函数,由记录的关键字确定记录在表中的位置信息,并将记录根据此信息放入表中,这样构成的表叫哈希表。哈希查找——利用哈希函数进行查找的过程。 除了特别简单的应用,在大多数情况下,所构造出的哈希函数是多对一的(非单射函数)。即可能有多个不同的关键字,它们对应的哈希函数值是相同的,这意味着不同记录由哈希函数确定的存储位置是相同的。这种情况被称为冲突。即: 若 key1 不等于 key2,而 h(key1)=h(key2)

Hash查找适合于关键字可能出现的值的集合远远大于实际关键字集合的情形。

根据抽屉原理,冲突是不可能完全避免的,所以,要解决:( 1 )构造一个性能好,冲突少的 Hash函数( 2 )如何解决冲突

Page 269: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、常用的哈希函数

( 1 )直接定址法构造:取关键字或关键字的某个线性函数作哈希地址,即H(key)=key 或 H(key)=a·key+b特点: 直接定址法所得地址集合与关键字集合大小相等,不会发生冲突 实际中能用这种哈希函数的情况很少。

此法仅适合于:地址集合的大小 = = 关键字集合的大小

Page 270: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

(2) 数字分析法 构造:对关键字进行分析,取关键字的若干位或其组合作哈希地址。

例 有 80 个记录,关键字为 8位十进制数,哈希地址为 2位十进制数

8 1 3 4 6 5 3 28 1 3 7 2 2 4 28 1 3 8 7 4 2 28 1 3 0 1 3 6 78 1 3 2 2 8 1 7 8 1 3 3 8 9 6 78 1 3 6 8 5 3 78 1 4 1 9 3 5 5

…..

…..

分析: 只取 8 只取 1 只取 3 、 4 只取 2 、 7 、 5 数字分布近乎随机所以:取任意两位或两位 与另两位的叠加作哈希地址

Page 271: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

此方法仅适合于: 能预先估计出全体关键字的每一位上各种

数字出现的频度。

(2) 数字分析法 构造:对关键字进行分析,取关键字的若干位或其组合作哈希地址。

Page 272: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

以关键字的平方值的中间几位作为存储地址。求“关键字的平方值” 的目的是“扩大差别” ,同时平方值的中间各位又能受到整个关键字中各位的影响。

( 3 )平方取中法

此方法适合于 : 关键字中的每一位都有某些数字重复出现频度很高的现象。

Page 273: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

( 4 )折叠法构造:将关键字分割成位数相同的几部分,然后取这几部

分的叠加和(舍去进位)做哈希地址。种类移位叠加:将分割后的几部分低位对齐相加间界叠加:从一端沿分割界来回折送,然后对齐相加。

例 关键字为 : 0442205864 ,哈希地址位数为 4

5 8 6 44 2 2 0

0 41 0 0 8 8

H(key)=0088

移位叠加5 8 6 40 2 2 4

0 4 6 0 9 2

H(key)=6092

间界叠加

Page 274: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

此方法适合于 : 关键字的数字位数特别多,且每一位上数字分布大致均匀情况。

( 4 )折叠法构造:将关键字分割成位数相同的几部分,然后取这几部

分的叠加和(舍去进位)做哈希地址。种类移位叠加:将分割后的几部分低位对齐相加间界叠加:从一端沿分割界来回折送,然后对齐相加。

Page 275: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

( 5 )除留余数法构造:取关键字被某个不大于哈希表表长m 的数 p 除

后所得余数作哈希地址,即 H(key)=key % p, pm

特点:简单、常用,可与上述几种方法结合使用p 的选取很重要; p 选的不好,容易产生同义词

( 6 )随机数法构造:取关键字的伪随机函数值作哈希地址,即

H(key)=random(key)

适于关键字长度不等的情况说明:• 哈希函数构造不应太复杂• 不存在绝对好和坏的函数

Page 276: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 、冲突解决A) 开放定址法

方法:当冲突发生时,形成一个探查序列;沿此序列逐个地址探查,直到找到一个空位置(开放的地址),将发生冲突的记录放到该地址中,即

Hi=(H(key)+di) % m, i=1,2,……k(km-1)

其中: H(key)——哈希函数 m——哈希表表长 di—— 增量序列分类线性探测再散列: di=1,2,3,……m-1

二次探测再散列: di=1²,-1²,2²,-2²,3²,……±k²(km/2)

伪随机探测再散列: di=伪随机数序列

Page 277: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

例 已知一组关键字 (19,14,23,1,68,20,84,27,55,11,10,79) 哈希函数为: H(key)=key % 13, 哈希表长为 m=16, 设每个记录的查找概率相等

用线性探测再散列处理冲突,即 Hi=(H(key)+di) % m

H(55)=3 冲突 ->H1=(3+1)%16=4 冲突 ->H2=(3+2)%16=5

H(79)=1 冲突 -> H1=(1+1)%16=2 冲突 -> H2=(1+2)%16=3 冲突 ->H3=(1+3)%16=4 冲突 -> H4=(1+4)%16=5 冲突 ->H5=(1+5)%16=6 冲突 -> H6=(1+6)%16=7 冲突 ->H7=(1+7)%16=8 冲突 ->H8=(1+8)%16=9

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1514 1 68 27 55 19 20 84 79 23 11 10

H(19)=6H(14)=1H(23)=10H(1)=1 冲突 ->H1=(1+1) %16=2H(68)=3H(20)=7

H(84)=6 冲突 ->H1=(6+1)%16=7 冲突 ->H2=(6+2)%16=8H(27)=1 冲突 ->H1 =(1+1)%16=2 冲突 -> H2=(1+2)%16=3 冲突 ->H2=(1+3)%16=4

H(11)=11

H(10)=10 冲突 ->H1=(10+1)%16=11 冲突 ->H2=(10+2)%16=12

Page 278: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

开放定址法的几个问题 1 )删除:只能作标记,不能真正删除 2 )溢出 3 )聚集问题

12345678

x

Page 279: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B) 链地址法 方法:将所有关键字为同义词的记录存储在一个单链表中,并用一维数组存放头指针。

例 :已知关键字 (19,14,23,1,68,20,84,27,55,11,10,79) 哈希函数: H(key)=key % 13 用链地址法处理冲突

20 ^

11 ^

0 ^12 ^3

8 ^9 ^

10

4 ^5 ^67

1112 ^

14 79 ^1 27

55 ^68

84 ^19

10 ^23

Page 280: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

Hash查找效率分析

装填因子 : 表容量表中记录数

查找成功:

11

)1ln(1

)1

11(

2

1

nc

nr

nl

s

s

s 线性探测再散列

随机探测再散列、二次探测

链地址

Page 281: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

Hash查找效率分析

装填因子 : 表容量表中记录数

查找不成功:

eU

U

U

nc

nr

nl

1

1

))1(

11(

2

12 线性探测再散列

伪随机探测再散列

链地址

Page 282: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

9.1 概述内部排序:全部数据可同时放入内存进行的排序。

外部排序:文件中数据太多,无法全部调入内存进行的排序。

定义:设有记录序列: { R1、 R2 ……….. Rn }

其相应的关键字序列为: { K1、 K2 ……….. Kn };

若存在一种确定的关系: Kx<= Ky<= … <=Kz

则将记录序列 { R1、 R2 ……….. Rn } 排成按关键字有序的序列 { Rx、 Ry ……….. Rz } 的操作,称之为排序。

关系是任意的,通常使用小于(递增)、大于(递减)等关系。

稳定与不稳定:若记录序列中的任意两个记录 Rx、 Ry 的关键字 Kx = Ky ;如果在排序之前和排序之后,它们的相对位置保持不变,则这种排序方法是稳定的,否则是不稳定的。

第九章 内部排序

Page 283: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

数据的存储可以是顺序、链表

约定:

1 )若不加说明,本章的数据以顺序方式利用一维数组 r存储

2 )数据最终的排序是递增序

3 )不失一般性,为简化算法,数据均以整型为例子

4 )排序的数据个数用 n 表示,

Page 284: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

1 2 3 4 5

36 24 10 6 12

Page 285: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

36 24 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 286: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

2436 24 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 287: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

2436 24 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 288: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

2436 36 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 289: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

2436 36 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 290: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

2424 36 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 291: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

2424 36 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 292: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

2424 36 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 293: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1024 36 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 294: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1024 36 10 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 295: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1024 36 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 296: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1024 36 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 297: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1024 24 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 298: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1024 24 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 299: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1010 24 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 300: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1010 24 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 301: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

1010 24 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 302: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 24 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 303: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 24 36 6 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 304: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 24 36 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 305: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 24 36 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 306: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 24 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 307: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 24 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 308: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 10 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 309: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

610 10 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 310: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

66 10 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 311: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

66 10 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 312: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

66 10 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 313: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

126 10 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 314: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

126 10 24 36 12

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 315: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

126 10 24 36 36

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 316: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

126 10 24 36 36

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 317: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

126 10 24 24 36

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 318: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

126 10 24 24 36

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 319: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 2 3 4 5

126 10 12 24 36

9.2 插入类排序1 、直接插入排序

方法:数据 r[1]到 r[i-1] 是有序的, r[i]到 r[n] 是任意次序的。将 r[i]插入到 r[1]到 r[i-1] 中并使得 r[1]到 r[i] 有序。

i 从 2 开始到结束进行 n-1 次。

Page 320: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

(2)C 语言描述(数组下标从 0 计)

void InsertSort(int r[ ],int n){

int i,j;int x;for(i=1;i<n;i++){

x=r[i];for(j=i-1;j>=0;j--)

if(r[j]>x) r[j+1]=r[j];

else break; r[j+1]=x;

}}

Page 321: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

测试主函数#define NUM 20#include <iostream.h>#include <stdlib.h>void printarr(int r[],int n){

int i;for(i=0;i<n;i++)

cout<<r[i]<<' ';cout<<endl;

}void main(){

int arr[NUM];int i;srand(1); // 初始化随机数发生器for(i=0;i<NUM;i++)

arr[i]=rand()%100; //随机数在 0到 99范围内InsertSort(arr,sizeof(arr)/sizeof(int));printarr(arr,sizeof(arr)/sizeof(int));

}

Page 322: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

(3) 分析

最坏情况是数据递减序,数据比较和移动量最大,达到O(n2)

最好是数据是递增序,比较和移动最少为 O(n)(4)折半插入排序

由于插入第 i 个元素到 r[1]到 r[i-1] 之间时,前 i 个数据是有序的,所以可以用折半查找确定插入位置,然后插入。

Page 323: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void BInsertSort (int r[],int n){ int i,low,high,m; int x; int j; for ( i = 1; i<=n-1 ; ++i ) { x= r[i]; low = 0 ; high = i-1 ; while ( low <= high ) { m = (low+high)>>1; if ( x< r[m]) high = m -1 ; else low = m + 1;

} for ( j=i-1; j>=high+1; --j ) r[j+1] = r[j];

r[high+1] = x; } } // BInsertSort

memmove(r+high+2,r+high+1,(i-1-high)*sizeof(int));

<string.h>

Page 324: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、 shell排序

希尔在 1959年针对插入排序作了改进,提出了一个缩小增量排序方法。

1) 方法:先取一个正整数 d1<n ,把所有相隔 d1 的数据作为一组,组内进行直接插入排序;然后取 d2<d1 ,重复上述分组和排序操作;直至 di=1。

Page 325: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

取 d3=1

三趟排序:4 13 27 38 48 49 55 65 76 97

例 初始: 49 38 65 97 76 13 27 48 55 4

一趟排序:13 27 48 55 4 49 38 65 97 76

二趟排序:13 4 48 38 27 49 55 65 97 76

取 d1=5一趟分组:49 38 65 97 76 13 27 48 55 4

取 d2=3二趟分组:13 27 48 55 4 49 38 65 97 76

Page 326: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 )一趟排序的方法,设间距是 d

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 27 48 55 4 49 38 65 97 76d=3: 55

Page 327: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 27 48 55 4 49 38 65 97 76d=3: 4

2 )一趟排序的方法,设间距是 d

Page 328: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 27 48 55 27 49 38 65 97 76d=3: 4

2 )一趟排序的方法,设间距是 d

Page 329: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 27 48 55 27 49 38 65 97 76d=3: 4

-2

2 )一趟排序的方法,设间距是 d

Page 330: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 55 27 49 38 65 97 76d=3: 4

-2

2 )一趟排序的方法,设间距是 d

Page 331: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 55 27 49 38 65 97 76d=3: 49

2 )一趟排序的方法,设间距是 d

Page 332: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 55 27 49 38 65 97 76d=3: 38

2 )一趟排序的方法,设间距是 d

Page 333: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 55 27 49 55 65 97 76d=3: 38

2 )一趟排序的方法,设间距是 d

Page 334: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 55 27 49 55 65 97 76d=3: 38

2 )一趟排序的方法,设间距是 d

Page 335: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 38 27 49 55 65 97 76d=3: 38

2 )一趟排序的方法,设间距是 d

Page 336: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 38 27 49 55 65 97 76d=3: 65

2 )一趟排序的方法,设间距是 d

Page 337: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 38 27 49 55 65 97 76d=3: 97

2 )一趟排序的方法,设间距是 d

Page 338: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

插入排序主体:for(i=1;i<n;i++){ x=r[i]; for(j=i-1;j>=0;j--) if(r[j]>x) r[j+1]=r[j]; else break; r[j+1]=x; }

for(i=d ;i<n;i++){ x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }

13 4 48 38 27 49 55 65 97 76d=3: 76

通过上述的基本代码,给以 d1(d1<n),d2,…dm=1,即可完成 shell排序

2 )一趟排序的方法,设间距是 d

Page 339: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

在实际应用中,步长的选取可简化为开始为表长 n 的一半( n/2),以后每次减半,最后为 1 。

void ShellSort(int r[],int n) { int i,j,d; int x; d=n/2; while(d>=1){ for(i=d ;i<n;i++) { x=r[i]; for(j=i-d;j>=0;j-=d) if(r[j]>x) r[j+d]=r[j]; else break; r[j+d]=x; }//for i d>>=1; }//while}//ShellSort

分析 : shell 排序的分析非常困难,原因是何种步长序列最优难以断定。通常认为时间 复杂性为: O( n3/2) .

较好的步长序列:…… 121 、 40 、 13 、 4、 1;

可由递推公式 Si= 3Si-1 + 1 产生。

Page 340: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

9. 3 交换类排序1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

97 76 13 27 4938 49 65

Page 341: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

97 76 13 27 4938 49 65

9. 3 交换类排序

Page 342: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

76 97 13 27 4938 49 65

9. 3 交换类排序

Page 343: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

76 97 13 27 4938 49 65

9. 3 交换类排序

Page 344: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

76 13 97 27 4938 49 65

9. 3 交换类排序

Page 345: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

76 13 97 27 4938 49 65

9. 3 交换类排序

Page 346: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

76 13 27 97 4938 49 65

9. 3 交换类排序

Page 347: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

76 13 27 97 4938 49 65

9. 3 交换类排序

Page 348: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 起 (冒)泡排序

原理 : n 个数据, r[1]与 r[2] 比较,大者在 r[2] 中, r[2]与比较r[3] ,大者在 r[3] ,依此类推, r[n-1]与 r[n] 比较,大者在 r[n] ,这样,一趟结束后, r[1]到 r[n] 中最大者在 r[n] 中;第二趟在 r[1]到r[n-1] 个数据中进行 ;按此方法,最后一趟在 r[1]与 r[2] 比较,大者在r[2] 。这样一共进行 n-1趟完成排序。

例: 将序列 49、 38、 65 、 97、 76 、 13 、 27、 49 用 起泡排序的方法进行排序。

97 76 13 27 4949 38 65

76 13 27 49 9738 49 65

下一趟在前 n-1个数据中进行

9. 3 交换类排序

Page 349: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2) C 语言描述:

3 )分析• 时间: O(n2)

• 通常认为冒泡是比较差的,可以加些改进,比如在一趟中无数据的交换,则结束等措施。

void bubblesort(int r[],int n){ int i,j; int x; for(i=n-1;i>0;i--)

for(j=0;j<i;j++)if(r[j]>r[j+1]) { x=r[j]; r[j]=r[j+1]; r[j+1]=x;}

}

Page 350: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void bubblesort(int r[],int n){ int i,j; int x; int flag; for(i=n-1;i>0;i--) { flag=1;

for(j=0;j<i;j++)if(r[j]>r[j+1]) { x=r[j]; r[j]=r[j+1]; r[j+1]=x;flag=0;}

if(flag) break; }}

• 在数据已基本有序时,冒泡是一个较好的方法• 在数据量较少时( 15 个左右)可以用冒泡

Page 351: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、快速排序1962年Hore提出

1 ) 原理 : 若序列中有 n 个元素,将第一个数据作为支点,将它放在表中合适的位置。以支点为界,序列分成两部分。其中左边数据小于等于支点,右半部分数据大于等于支点。然后,对左右两部分分别进行递归处理,直至排好序为止。

Page 352: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 13 27 6949 38 65

i j

Page 353: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 13 27 6949 38 65

i j

Page 354: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 13 49 6927 38 65

i j

Page 355: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 13 49 6927 38 65

i j

Page 356: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 13 49 6927 38 65

i j

Page 357: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 13 65 6927 38 49

i j

Page 358: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 13 65 6927 38 49

i j

Page 359: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 49 65 6927 38 13

i j

Page 360: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

97 76 49 65 6927 38 13

i j

Page 361: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

49 76 97 65 6927 38 13

i j

Page 362: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

49 76 97 65 6927 38 13

i j

Page 363: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2)将支点放在表合适位置——划分算法 设两个指针, i和 j, 开始分别指向表的开始与结束,任一时刻,支点或在 i处(开始在 i处) , 或在 j处。 支点在 i处:若 r[i]<=r[j], 两者位置合适, j减 1;否则,两者位置不合适, r[i]与 r[j] 对换, i 加 1 ; 支点在 j处:若 r[i]<=r[j], 两者位置合适, i 加 1;否则,两者位置不合适, r[i]与 r[j] 对换, j减 1 ; 重复直到 i与 j 相等。

49 76 97 65 6927 38 13

i j

Page 364: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

int partion(int r[],int i,int j){ int x; x=r[i]; while(i<j) { while(i<j && x<=r[j]) j--; if(i<j) { r[i]=r[j];

i++; } while(i<j && r[i]<=x) i++; if(i<j) { r[j]=r[i];

j--; } } r[i]=x; return i;}

void qsort(int r[],int l,int h){ int m; if(l<h) { m=partion(r,l,h);

qsort(r,l,m-1); qsort(r,m+1,h); }

}

void quiksort(int r[],int n) {

qsort(r,0,n-1); }

3)排序的 C 语言算法

Page 365: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4) 分析

A)时间复杂度 最好情况(每次支点总是在中

间) T(n)=O(nlog2n)

平均 T(n)=O(nlog2n)

最坏情况(数据已是递增或递减) T(n)=O(n²)

B) 空间复杂度:需栈空间以实现递归最坏情况: S(n)=O(n)一般情况: S(n)=O(log2n)

Page 366: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

C)快速排序的不足和克服方法• 最坏情况下 时间复杂性为 O(n2) 级。如:在序列已是有序的情况下。 10 20 30 40 50 60 70 80 支点 10

[10][20 30 40 50 60 70 80] 原因:支点选择不当。

改进:随机选取支点或最左、最右、中间三个元素中的值处于中间的作为支点,通常可以避免最坏情况。

所以,快速排序在表已基本有序的情况下不合适。

• 在序列长度已较段短时,采用直接插入排序、起泡排序等排序方法。序列的个数通常取 10左右。

Page 367: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

快速排序 C/C++ 接口

头文件 : stdlib.h

函数原型:

qsort(void *base, int element, int size , int (*fcmp)(const void *,const void *))

其中: fcmp 为返回整型数的比较函数,规定: 第一个数据小于第二个,返回小于 0 的数 第一个数据等于第二个,返回 0 第一个数据大于第二个,返回大于 0 的数

Page 368: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

#include <iostream.h>#include <stdlib.h>#define NUM 20cmp(const void *a, const void *b){

if(*(int *)a>*(int *)b) return 1;else if(*(int *)a==*(int *)b) return 0;else return -1;

}void main(){

int i;int a[NUM];for(i=0;i<NUM;i++)

a[i]=rand()%100;qsort(a,sizeof(a)/sizeof(int),sizeof(int),cmp);for(i=0;i< sizeof(a)/sizeof(int);i++)

cout<<a[i]<<' ';cout<<endl;

}

Page 369: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

9.4 选择类排序

1) 方法:第一趟在 r[1]到 r[n] 中挑出最小的,放在 r[1]

第二趟在 r[2]到 r[n] 中挑出最小的,放在 r[2]

依此类推:最后一趟在 r[n-1]和 r[n]挑出小者,放在 r[n-1]

这样,共进行 n-1趟

1 、 简单选择排序

2)时间: O(n2)

总比较次数:( n-1)+(n-2)+ …. +2+1=n(n-1)/2

Page 370: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

49 38 65 97 76 13 27一趟:

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

Page 371: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

49 38 65 97 76 13 27一趟:

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

Page 372: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

49 38 65 97 76 13 27一趟:

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

Page 373: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

49 38 65 97 76 13 27一趟:

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

Page 374: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

49 38 65 97 76 13 27一趟:

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

Page 375: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

13 38 65 97 76 49 27一趟:

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

Page 376: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

13 38 65 97 76 49 27二趟:

Page 377: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

13 38 65 97 76 49 27二趟:

Page 378: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3 ) 例子

k (蓝色)在算法中记当前最小值的位置, j(红色)当前比较的点

13 27 65 97 76 49 38二趟:

4)C 语言描述 void selectsort(int a[],int n){

int i,j,k;int x;for(i=0;i<n-1;i++){ k=i; for(j=i+1;j<n;j++) if(a[j]<a[k]) k=j; x=a[k];

a[k]=a[i];a[i]=x;

}}

Page 379: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

改进思路:简单选择排序没有利用上次选择的结果,是造成速度慢的重要原因。如果,能够加以改进,将会提高排序的速度。

2 、堆排序

38 1376 276549 97 49

38 65 13 27

1338

13

选出最小者 13

Page 380: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

38 76 276549 97 49

38 65 76 27

2738

27

选出次最小者 27,应利用上次比较的结果。从被 13 打败的结点 27、 76 、 38 中加以确定。

Page 381: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 )堆排序 堆的定义: n 元素的序列 { k1 , k2 …… , , kn } ,当且仅当对任一 ki

满足以下关系时,称之为堆:

ki <= k2i ki >= k2i

ki <= k2i+1 ki >= k2i+1

且分别称之为最小化堆和最大化堆。

例: { 96,83,27,11,9} 最大化堆

{ 12 , 36 , 24 , 85 , 47, 30 , 53 , 91} 最小化堆

96

911

83 27

2 3

1

4 5

1

12

4785

91

36 24

5330

6

2

7

3

8

4 5

Page 382: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

60

40

70

1

2

4

30

5

12

8 3

6

root

10

7

堆可以利用一维数组存储

1

2

3

4

5

6

7

70

60

12

40

30

8

10

Page 383: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

90

80

18

76 32 5648

57

3123

Page 384: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

60

80

18

76 32 5648

57

3155

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 385: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

80

60

18

76 32 5648

57

3155

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 386: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

80

76

18

60 32 5648

57

3155

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 387: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

10

80

18

76 32 5648

57

3170

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 388: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

80

10

18

76 32 5648

57

3170

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 389: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

80

76

18

10 32 5648

57

3170

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 390: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

80

76

18

70 32 5648

57

3110

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 391: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void sift(r[],k,m)

//k筛选标号,m 筛选范围{ i=k; j=2*i;x=r[i]; while(j<=m) { if(j<m &&r[j]<r[j+1]) j++; if(x<r[j]) { r[i]=r[j]; i=j; j<<=1; }//j*2

else j=m+1; }

r[i]=x; }

3)Floyed筛选算法 设数据在 r[1]到 r[n] 中,作为一棵完全二叉树,二叉树的左、右子树都是堆,现在将根考虑进去,保证二叉树仍是堆。•完全二叉树只有一个结点(即为叶),不需处理•根的值比两个儿子的值都大(大顶堆,小顶堆反之定义),不需处理•根的数据与值大的儿子值对换,问题转换成对子树的处理问题。

Page 392: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

97 76 13 69 4949 38 65

49

49

38 65

97 76 13 69

Page 393: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

97 76 13 69 4949 38 65

49

49

38 65

97 76 13 69

Page 394: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

97 76 13 65 4949 38 69

49

49

38 69

97 76 13 65

Page 395: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

97 76 13 65 4949 38 69

49

49

38 69

97 76 13 65

Page 396: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

38 76 13 65 4949 97 69

49

49

97 69

38 76 13 65

Page 397: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

49 76 13 65 3849 97 69

38

49

97 69

49 76 13 65

Page 398: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

49 76 13 65 3849 97 69

38

49

97 69

49 76 13 65

Page 399: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

49 76 13 65 3897 49 69

38

97

49 69

49 76 13 65

Page 400: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

49 49 13 65 3897 76 69

38

97

76 69

49 49 13 65

最大者在 r[1] 中

下一步 r[1]与 r[n] 对换

Page 401: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )建立初始堆:从标号最大的有孩子的点 i 开始筛选,( i=n整除 2 ) ,然后 i减

1 ,直到 i 为 1 为止。

49 49 13 65 9738 76 69

97

38

76 69

49 49 13 65

此时可理解为 r[n] 在逻辑上已不是二叉树的一个部分,原来 r[n] 的数据放在 r[1] 后,其左,右子树还是堆结构没有破坏,所以对 r[1] 进行一次筛选,次大的又出现在 r[1] 中,然后 ,r[1]与 r[n-1]再对换。如此类推,最后在r[1]与 r[2] 之间进行一次,排序完成。

Page 402: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

for(i=n/2;i>=1;i--) sift(r,i,n); for(i=n;i>=2;i--) { r[1] r[i]; sift(r,1,i-1); }}

5) 算法结构 若考虑 C/C++ 语言中 n个数据存储在 r[0]到 r[n-1] 中,双亲与孩子之间的标号关系如下:

49

49

38 65

97 76 13 69

0

1 2

3 54 6

7

i 的左孩子: i*2+1 (i*2+1 <=n)

右孩子: i*2+2 (i*2+2<=n)

Page 403: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

6)C 语言描述

void sift(int r[],int k,int m)//k筛选标号, m筛选范围{ int i,j,x; i=k; j=2*i+1 ;x=r[i]; while(j<=m) { if(j<m &&r[j]<r[j+1]) j++; if(x<r[j]) { r[i]=r[j]; i=j; (j<<=1)++; }//j*2+1 else j=m+1; } r[i]=x; }

void heapsort(int r[],int n){ int i; int x; for(i=n>>1-1;i>=0;i--) sift(r,i,n-1); for(i=n-1;i>=1;i--) { x=r[0]; r[0]=r[i];

r[i]=x; sift(r,0,i-1); }}

Page 404: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

7)时间: 建堆 O(n)

筛选 O(nlogn)

Page 405: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

9.5 归并排序

Page 406: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5

Page 407: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 8

Page 408: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98

Page 409: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9

Page 410: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11

Page 411: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23

Page 412: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25

Page 413: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25 30

Page 414: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25 30 40

Page 415: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25 30 5440

Page 416: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25 30 5440 61

Page 417: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25 30 5440 61 63

Page 418: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25 30 5440 61 63 70

Page 419: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

归并:将已排序的若干个表合并成一个有序表。当将两个有序表归并为一个时称为 2- 路归并。

1 ) 2- 路归并:

5 239 54 61 63 70

8 119 25 30 40

5 98 9 11 23 25 30 5440 61 63 70

时间:与表长成正比,若一个表表长是 m ,另一个是 n ,则时间是 O(m+n)

Page 420: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2) 程序描述:

void merge(int sr[],int tr[],int l,int m,int n){

int i,j,k;i=l;j=m+1;k=l-1;while(i<=m && j<=n) if(sr[i]<sr[j]) tr[++k]=sr[i++]; else tr[++k]=sr[j++];while(i<=m) tr[++k]=sr[i++];while(j<=n)tr[++k]=sr[j++];for(i=l;i<=n;i++) sr[i]=tr[i];

}

有序段 1 有序段 2

有序段

有序段

sr

sr

tr

l m n

Page 421: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

3)归并排序

开始将数据看成长度为 1 的有序表,两两归并为长度为 2 的表,依次类推直到长度为 n 的有序表

子表长: 19 7 8 3 52 4 16

子表长: 27 9 3 8 4 52 16

子表长: 43 7 8 9 4 16 52

子表长: 73 4 7 8 9 16 52

Page 422: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

4 )归并排序描述void msort(int r[],int st[],int s,int t){ int m; if(s<t) { m=(s+t)>>1;

msort(r,st,s,m); msort(r,st,m+1,t); merge(r,st,s,m,t);}

}

void mergesort(int r[],int n){

int *st=new int[n];msort(r,st,0,n-1); delete st;

}

5 )分析

时间: O(nlogn)

空间: O(n)

Page 423: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void merge(int sr[],int tr[],int l,int m,int n){ int i,j,k; i=l; j=m+1; k=l-1; while(i<=m && j<=n) if(sr[i]<sr[j]) tr[++k]=sr[i++]; else tr[++k]=sr[j++]; while(i<=m) tr[++k]=sr[i++]; while(j<=n)tr[++k]=sr[j++]; for(i=l;i<=n;i++) sr[i]=tr[i];}

5) merge 的修改提高效率

void merge(int sr[ ],int tr[],int l,int m,int n){ int i,j,k; i=l; j=m+1; k=l-1; while(i<=m && j<=n) if(sr[i]<sr[j]) tr[++k]=sr[i++]; else tr[++k]=sr[j++]; memmove(tr+k+1,sr+i,sizeof(int)*(m-i+1)); memmove(tr+k+1,sr+j,sizeof(int)*(n-j+1)); memcpy(sr+l,tr+l,sizeof(int)*(n-l+1));}

Page 424: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

if(s<t) { m=(s+t)>>1; msort(r,st,s,m); msort(r,st,m+1,t); merge(r,st,s,m,t);}

s t

9 7 8 3 52 4 16

9 7 8 3 52 4 16

9 7 8 3 52 4 16

Page 425: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

一个数据看成有 t位组成,( K1 ,K2, …… Kt ),作为一个元组,大小按字典序定义

1 、基数排序:

基数排序实例:

假定给定的是 t = 2 位的十进制数,现要求通过基数排序法将其排序。

方法:设置 若干桶,因十进制数分别有数字: 0 , 1 , 2 ,…… 9 ,所以设置十个桶,分别用 B0 、 B1 、 B2 、 …… B9 进行标识。

排序分两步

( 1 )分配:将右起第 j 位数字相同的数放入同一桶。比如数字为 1 者, 则放入桶

B1 。其余类推 ……

( 2 )收集:按 B0 、 B1 、 B2 、 …… B9 的顺序进行收集。 重复( 1 )( 2 )从最右位直到最左位共 t 次。(位数不够者,左边补 0 ,如 3看成 03 )

9.6基数排序

Page 426: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

Page 427: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 428: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 429: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 430: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 431: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 432: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 433: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

7

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 434: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

7

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 435: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

7

18

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 436: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

7

18

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 437: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

7

18

17

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 438: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

7

18

17

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 439: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

5

2

9

7

18

17

52

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 440: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

桶 分配完毕,按照红色

箭头所指的方向进行

收集动作。注意:收

集后的序列已经按照

右起第一位(个位数

字)排好序了。5

2

9

7

8

17

52

收集后的序列:

2 52 5 7 17 8 9

例子 : B = 5、 2、 9、 7、 18、 17、 52 用基数排序法进行排序。

B = 05、 02、 09、 07、 18、 17、 52

Page 441: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

Page 442: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 443: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 444: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 445: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 446: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 447: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 448: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05 07

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 449: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05 07

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 450: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05 07

17

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 451: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05 07

17

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 452: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05 07

17

08

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 453: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05 07

17

08

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 454: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

根据 所指向的

数,进行分配动作,

将其分配到相应的桶

。和第一次不同,这次根据右起第二位

数字(十位数字)进

分配。

02

52

05 07

17

08 09

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 455: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

02

52

05 07

17

08 09

分配完毕,按照红色

箭头所指的方向进行

第二次收集动作。注

意:收集后的序列已

经按照右起第一位(

个位数字)、右起第

二位(十位数字)排

好序了。

收集后的序列: 2 、 5 、 7 、 8 、 9 、 17、 52

已是排好序的序列。

B = 02、 52、 05、 07、 17、 08、 09 (第一次收集的结果)

Page 456: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

2 、 分析:

时间:上例中每个数有 t = 2 位,因此执行 t = 2 次分配和收集就可以了。在一般情况下,每个结点有 d 位关键字,必须执行 t = d 次分配和收集操作。

分配的代价: O(n)

收集的代价: O(rd) ( rd 是基数)

总的代价为: O( d ×(n + rd))

Page 457: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

1 、 各种方法的时、空优劣

2 、 比较法分类的下界: O(nlogn )

9.7 各种内部排序方法的比较讨论

Page 458: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

第 10 章 外部排序

Page 459: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

步骤:• 生成合并段( run):读入文件的部分记录到内存 - > 在内存中进行内部排序 - >

将排好序的这些记录写入外存,形成合并段 - > 再读入该文件

的下面的记录,往复进行,直至文件中的记录全部形成合并段

为止。• 外部合并:将上一阶段生成的合并段调入内存,进行合并,直至最后形成一个有序的文

件。

7 、 15 、 19 8 、 11 、 13 16 、 23 、 31 5 、 12

外部排序的方法

根据内存容量设若干个输入缓冲区和一个输出缓冲区。若采用二路归并,用两个输入缓冲。

归并的方法类似于归并排序的归并算法。增加的是对缓冲的监视,对于输入,一旦缓冲空,要到相应文件读后续数据,对于输出缓冲,一旦缓冲满,要将缓冲内容写到文件中去。

Page 460: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

第 11 章 有效算法的设计

1 、贪心法 2 、回溯法 3 、分支限界法 4 、分治法 5 、动态规划

Page 461: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

处理大规模问题时,求解可能比较困难,对于这类问题,往往把它分 解为若干个子问题求解,求出几个子问题后,在找合适的方法,把它们组合成整个问题的解。如果处理子问题仍然困难,则再次进行分割,直到可以直接求解为止。这种大化小的策略称为分治策略。

分治法

一般步骤:( 1 )分割:将要解决的问题划分成若干规模较小的同类问题。( 2 )求解:当子问题划分得足够小时,用简单的方法解决。( 3 )合并:按原问题的要求,将子问题的解逐层合并构成原问

题的解。例子:二分查找、归并排序、快速排序等

Page 462: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

动态规划

例子: 设有一个三角形塔,顶点为根,每个结点有一个整数数值。从顶点出发可以向左,也可以向右。

13

11 8

26712

15146 8

13712 24 11

问题:当一个三角形塔给出后,找出一条从根到底层的路径,使路径上的值最大。

Page 463: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分析:( 1 )贪心法往往得不到最优解

13

11 8

26712

15146 8

13712 24 11

Page 464: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分析:( 1 )贪心法往往得不到最优解

13

11 8

26712

15146 8

13712 24 11

Page 465: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分析:( 1 )贪心法往往得不到最优解

13

11 8

26712

15146 8

13712 24 11

Page 466: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分析:( 1 )贪心法往往得不到最优解

13

11 8

26712

15146 8

13712 24 11

Page 467: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分析:( 1 )贪心法往往得不到最优解

13

11 8

26712

15146 8

13712 24 11

路径长度: 13+11+12+14+13=63

Page 468: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分析:( 1 )贪心法往往得不到最优解

13

11 8

26712

15146 8

13712 24 11

路径长度: 13+11+12+14+13=63

路径长度: 13+8+26+15+24=86

Page 469: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

分析:( 1 )贪心法往往得不到最优解( 2 )穷举法往往是不可能的

13

11 8

26712

15146 8

13712 24 11

当数塔的层次较大时,路径就非常多。设数塔的层数为 n ,路径数是 P ,则 P和 n 的关系为:n=1 P=1n=2 P=2n=3 P=4…………………………n=k P=2k-1

若 n=50, 则 P=249 ,大约为 500万亿

Page 470: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

动态规划求解: 采用:自顶向下分析,自底向上求解

13

11 8

26712

15146 8

13712 24 11

xy

x: 从 11 出发到达底的最大路径y: 从 8 出发到达底的最大路径

if( x>y) 选择 x, 且能得到的最大值是 13+x else 选择 y, 且能得到的最大值是 13+y;

从根出发查找最大路径长的问题成为分别从 11 和 8 出发查找路径最大值的子问题。

Page 471: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

方法: ( 1 )从底层开始,本身数值即为最大值

13

11 8

26712

15146 8

13712 24 1112 7 13 24 11

Page 472: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

方法: ( 1 )从底层开始,本身数值即为最大值

13

11 8

26712

15146 8

13712 24 1112 7 13 24 11

( 2 )倒数第二层的计算,将决定于底层

18 27 39 31

( 3 )依此类推,直到顶层

39 46 65

57 73

86

Page 473: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

方法: ( 1 )从底层开始,本身数值即为最大值

13

11 8

26712

15146 8

13712 24 1112 7 13 24 11

( 2 )倒数第二层的计算,将决定于底层

18 27 39 31

( 3 )依此类推,直到顶层

39 46 65

57 73

86

Page 474: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

方法: ( 1 )从底层开始,本身数值即为最大值

13

11 8

26712

15146 8

13712 24 1112 7 13 24 11

( 2 )倒数第二层的计算,将决定于底层

18 27 39 31

( 3 )依此类推,直到顶层

39 46 65

57 73

86

Page 475: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

18 27 39 31

方法: ( 1 )从底层开始,本身数值即为最大值

13

11 8

26712

15146 8

13712 24 1112 7 13 24 11

( 2 )倒数第二层的计算,将决定于底层 ( 3 )依此类推,直到顶层

39 46 65

57 73

86

Page 476: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

12 7 13 24 11

18 27 39 31

方法: ( 1 )从底层开始,本身数值即为最大值

13

11 8

26712

15146 8

13712 24 11

( 2 )倒数第二层的计算,将决定于底层 ( 3 )依此类推,直到顶层

39 46 65

57 73

86

Page 477: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

问题求解:数塔表示

13

11 18

12 7 26

6 14 15 8

12 7 13 24 11

可以用下三角矩阵表示

Page 478: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

13

11 18

12 7 26

6 14 15 8

12 7 13 24 11

数据结构:每个点有三个数据描述:val: 值本身数值max: 能取得的最大值de: 方向, 0 向下,

1 右下。

#define NUM 5struct St{ int val;int max;int de; };

St g[NUM][NUM];

Page 479: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

#include <iostream.h>#include <iomanip.h>#include <stdlib.h>#define NUM 5struct St{ int val;int max;int de; };

void eva(St g[][NUM],int n){ int i,j; for(i=n-2;i>=0;i--) for(j=0;j<=i;j++) if(g[i+1][j].max>g[i+1][j+1].max) g[i][j].max=g[i][j].val+g[i+1][j].max; else { g[i][j].max=g[i][j].val+g[i+1][j+1].max;

g[i][j].de=1;}}

Page 480: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

void output(St g[][NUM],int n){ int i,j; int mm=0; for(i=0;i<NUM;i++) { for(j=0;j<=i;j++)

cout<<setw(3)<<g[i][j].val<<' ';

cout<<endl;}cout<<g[0][0].val;j=0;

for(i=0;i<n-1;i++) {

j+=g[i][j].de;mm+=g[i+1][j].val;cout<<"->"<<g[i+1][j].val;}cout<<':'<<mm<<endl;

}

void main(){ St g[NUM][NUM]; int i,j; for(i=0;i<NUM;i++) for(j=0;j<NUM;j++) { if(i>=j) g[i][j].max=g[i][j].val=rand()%100; else g[i][j].val=0; g[i][j].de=0;} eva(g,NUM); output(g,NUM);}

Page 481: 1、 图的定义和术语 2、图的存储结构 3、图的遍历 4、图的连通性问题 5、有向无环图及其应用 6、最短路径

动态规划解题的方法是一种高效率的方法,其时间复杂度通常为 O(n2), O(n3) 等,可以解决相当大的信息量。(数塔在n<=100层时,可以在很短的时间内得到问题解) 适用的原则:原则为优化原则,即整体优化可以分解为若干个局部优化。• 动态规划比穷举法具有较少的计算次数• 递归算法需要很大的栈空间,而动态规划不需要栈空间

数据结构课程中属于动态规划的有: Dijkstra 的最短路径、 Prim求最小生成树的 O(n2) 的算法、关键路径及关键活动的求法。