数据结构教程--图的遍历及生成树
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• 深度优先搜索 广度优先搜索
深度优先搜索
• 首先访问出发顶点v0 • 选择一个与v0相邻接的且末访问过的顶点w访问 • 再从w开始,按深度优先搜索…..
• 每当到达一个其所相邻接的顶点都已被访问过的 顶点,则从最后所访问的顶点开始,依次退回到尚 有邻接顶点末曾访问过的顶点u,并从u开始进行 深序优先搜索…..
visited[i]=0; for(i=1;i<=n;i++) if (visited[i]==0)
教材:P235 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9
图的遍历与求图的连通分量
• 图的遍历:
从给定图中任意指定的顶点出发,按照某 种方式系统地访问图中的顶点,使每个顶点仅被 访问一次,所得到的一个序列
• 访问标志位visit[ ]
– 遍历前置visit的各元素为0 – 若顶点vi被访问过,则置visit[i]为1
t=t->link;} }
广度优先搜索法
• 首先访问出发点v • 然后访问与顶点v邻接的全部顶点w1,w2,….,wt • 再依次访问与w1,w2,….,wt邻接的全部结点(已访问
过的顶点除外) • 再从这些已访问的顶点出发,依次访问与它们邻接
的全部顶点(已访问的顶点除外) • 依次类推,直到图中所有顶点都访问到或出发顶点V
void init(n) int n; { int i;
for (i=1;i<=n;i++) visit[i]=0;
}
void dfs(u) int u; { L_NODE *t;
visit[u]=1; printf(“%d”,u); t=head[u]; while(t!=NULL)
{ if (visБайду номын сангаасt[t->ver]= =0) dfs(t->ver);
所在的连通分量的所有顶点都有被访问到为止
1
2 5
4 8
3
6
7
9
1
4
6
5
2
7
3
1 3
4
广度优先搜索法
1 22
2
3
4^
1
3
5^
53 4 5
1
2
1
3
2
3
4
5^
5^
4^
广度优先搜索法
1. 把队列置空 2. 输出出发顶点,置该顶点已被访问的标志 3. 让出发顶点进队 4. 若队列不空,则
– 取出队首中的顶点V – 在邻接表中,依次取得与顶点V邻接的各个顶点 – 转(4)
• 若队列空,则处理过程结束
void bfs(u) int u; {struct queuetype {int qa;
int qe; int item[MAXN];} typedef struct queuetype QTYPE; int v,w; L_NODE *t; QTYPE queue; printf(“%4d”,u); visit[u]=1; queue.qa=0;queue.qe=0 queue.item[0]=u;
1.在一个无向图中,所有顶点的度数之和等于所有边 数的 ( )倍.
A.1/2 B.1 C.2 D.4 2.在一个有向图中,所有顶点的入度之和等于所有顶
点的出度之和的( )倍
A.1/2 B.1 C.2 D.4 3.一个有N个顶点的无向图最多有( )条边.
A.N B.N(N-1) C.N(N-1) /2 D.2N
4
深度优先搜索
1 22
2
3
1
3
53 4 5
1
2
1
3
2
3
4^ 5^
4
5^
5^
4^
#include <stdio.h> #define MAXN 50 #define MAXN 100 struct l_node {int ver;
struct l_node *link;}; typedef struct l_node L_NODE; typedef struct{int ver1;
5.具有6个顶点的无向图至少应有( )条边才能 确保是一个连通图.
A.5 B.6 C.7 D.8 6.对于一个具有N个顶点和E条边的无向图,若采用 邻接表表示,则表头向量的大小为( ),所有邻接 表中的结点总数是( ).
A.N B.N+1 C.N-1 D.N+E
A.E/2 B.E C. 2E D.N+E
• 直到所有顶点都访问过或从任何一个已访问过的 顶点出发,再也无法到达末曾访问过的顶点
1
2 5
4 8
3
6
7
9
1
4
6
5
2
7
3
1
2
3
4
5
G=(V,E) V=(1,2,3,4,5) E={ (4,5) ,(3,5) ,(3,4), (2,5), (2,3), (1,4), (1,3),(1,2)}
1 3
while(queue.qa<=queue.qe) { v=queue.item[queue.qa++]; t=head[v]; while(t!=NULL) {w=t->ver; if(visit[w]==0) {printf(“%4d”,w); visit[w]=1; queue.item[++queue.qe]=w; } t=t->link; } }
}
求图的连通分量
• 对图的每一个顶点进行检验
– 若被访问过,则该顶点落在已被求出的连通分 量上
– 若末被访问过,则从该顶点出发遍历图,便可 求得图的另一个连通分量
int count( l_node *head, int n) {int count i;
count=0 for(i=1;i<=n;i++)
int ver2;} E_NODE; L_NODE *head[MAXN]; int visit[MAXN]; E_NODE e[MAXN]; int n,m,u;
void creat_adj_list(head,n,e,m) L_NODE *head[ ]; E_NODE e[ ]; int n,m; {int i,u,v; L_NODE *p; for (i=1;i<=n;i++) head[i]=NULL; for(i=0;i<m;i++) { u=e[i].ver1; v=e[i]=ver2; p=(L_NODE*)moalloc(sizeof(L_NODE)); p->ver=v; p->link=head[u];head[u]=p; p=(L_NODE*)moalloc(sizeof(L_NODE)); p->ver=u; p->link=head[v];head[v]=p;} }
深度优先搜索
• 首先访问出发顶点v0 • 选择一个与v0相邻接的且末访问过的顶点w访问 • 再从w开始,按深度优先搜索…..
• 每当到达一个其所相邻接的顶点都已被访问过的 顶点,则从最后所访问的顶点开始,依次退回到尚 有邻接顶点末曾访问过的顶点u,并从u开始进行 深序优先搜索…..
visited[i]=0; for(i=1;i<=n;i++) if (visited[i]==0)
教材:P235 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9
图的遍历与求图的连通分量
• 图的遍历:
从给定图中任意指定的顶点出发,按照某 种方式系统地访问图中的顶点,使每个顶点仅被 访问一次,所得到的一个序列
• 访问标志位visit[ ]
– 遍历前置visit的各元素为0 – 若顶点vi被访问过,则置visit[i]为1
t=t->link;} }
广度优先搜索法
• 首先访问出发点v • 然后访问与顶点v邻接的全部顶点w1,w2,….,wt • 再依次访问与w1,w2,….,wt邻接的全部结点(已访问
过的顶点除外) • 再从这些已访问的顶点出发,依次访问与它们邻接
的全部顶点(已访问的顶点除外) • 依次类推,直到图中所有顶点都访问到或出发顶点V
void init(n) int n; { int i;
for (i=1;i<=n;i++) visit[i]=0;
}
void dfs(u) int u; { L_NODE *t;
visit[u]=1; printf(“%d”,u); t=head[u]; while(t!=NULL)
{ if (visБайду номын сангаасt[t->ver]= =0) dfs(t->ver);
所在的连通分量的所有顶点都有被访问到为止
1
2 5
4 8
3
6
7
9
1
4
6
5
2
7
3
1 3
4
广度优先搜索法
1 22
2
3
4^
1
3
5^
53 4 5
1
2
1
3
2
3
4
5^
5^
4^
广度优先搜索法
1. 把队列置空 2. 输出出发顶点,置该顶点已被访问的标志 3. 让出发顶点进队 4. 若队列不空,则
– 取出队首中的顶点V – 在邻接表中,依次取得与顶点V邻接的各个顶点 – 转(4)
• 若队列空,则处理过程结束
void bfs(u) int u; {struct queuetype {int qa;
int qe; int item[MAXN];} typedef struct queuetype QTYPE; int v,w; L_NODE *t; QTYPE queue; printf(“%4d”,u); visit[u]=1; queue.qa=0;queue.qe=0 queue.item[0]=u;
1.在一个无向图中,所有顶点的度数之和等于所有边 数的 ( )倍.
A.1/2 B.1 C.2 D.4 2.在一个有向图中,所有顶点的入度之和等于所有顶
点的出度之和的( )倍
A.1/2 B.1 C.2 D.4 3.一个有N个顶点的无向图最多有( )条边.
A.N B.N(N-1) C.N(N-1) /2 D.2N
4
深度优先搜索
1 22
2
3
1
3
53 4 5
1
2
1
3
2
3
4^ 5^
4
5^
5^
4^
#include <stdio.h> #define MAXN 50 #define MAXN 100 struct l_node {int ver;
struct l_node *link;}; typedef struct l_node L_NODE; typedef struct{int ver1;
5.具有6个顶点的无向图至少应有( )条边才能 确保是一个连通图.
A.5 B.6 C.7 D.8 6.对于一个具有N个顶点和E条边的无向图,若采用 邻接表表示,则表头向量的大小为( ),所有邻接 表中的结点总数是( ).
A.N B.N+1 C.N-1 D.N+E
A.E/2 B.E C. 2E D.N+E
• 直到所有顶点都访问过或从任何一个已访问过的 顶点出发,再也无法到达末曾访问过的顶点
1
2 5
4 8
3
6
7
9
1
4
6
5
2
7
3
1
2
3
4
5
G=(V,E) V=(1,2,3,4,5) E={ (4,5) ,(3,5) ,(3,4), (2,5), (2,3), (1,4), (1,3),(1,2)}
1 3
while(queue.qa<=queue.qe) { v=queue.item[queue.qa++]; t=head[v]; while(t!=NULL) {w=t->ver; if(visit[w]==0) {printf(“%4d”,w); visit[w]=1; queue.item[++queue.qe]=w; } t=t->link; } }
}
求图的连通分量
• 对图的每一个顶点进行检验
– 若被访问过,则该顶点落在已被求出的连通分 量上
– 若末被访问过,则从该顶点出发遍历图,便可 求得图的另一个连通分量
int count( l_node *head, int n) {int count i;
count=0 for(i=1;i<=n;i++)
int ver2;} E_NODE; L_NODE *head[MAXN]; int visit[MAXN]; E_NODE e[MAXN]; int n,m,u;
void creat_adj_list(head,n,e,m) L_NODE *head[ ]; E_NODE e[ ]; int n,m; {int i,u,v; L_NODE *p; for (i=1;i<=n;i++) head[i]=NULL; for(i=0;i<m;i++) { u=e[i].ver1; v=e[i]=ver2; p=(L_NODE*)moalloc(sizeof(L_NODE)); p->ver=v; p->link=head[u];head[u]=p; p=(L_NODE*)moalloc(sizeof(L_NODE)); p->ver=u; p->link=head[v];head[v]=p;} }