图算法(二):深度优先遍历原理与应用

一、基本概念

1、定义

    首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。

若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。

2、特点

    类似于树的前序遍历,尽可能先对纵深方向进行搜索。

3、基本思想

(1)访问顶点v;

(2)从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;

(3)重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

4、伪代码

递归实现:

(1)访问顶点v;visited[v]=1;//算法执行前visited[n]=0

(2)w=顶点v的第一个邻接点;

(3)while(w存在)

if(w未被访问

从顶点w出发递归执行该算法;

w=顶点v的下一个邻接点;

非递归实现:(结合

(1)栈S初始化;visited[n]=0;

(2)访问顶点v;visited[v]=1;顶点v入栈S

(3)while(栈S非空)

x=栈S的顶元素(不出栈);

if(存在并找到未被访问的x的邻接点w)

访问w;visited[w]=1;

w进栈;

else

x出栈;

5、实现

输入图像:

        A

                   / 

                 B     C

              /       / 

            D    E   F--G

                 /

         H

程序:

N = 8

 

visited = [0] * N

stack = []

Graphic = [[0,1,1,0,0,0,0,0],[1,0,0,1,1,0,0],[1,0,0,0,0,1,1,0],[0,1,0,0,0,0,0,1],[0,1,0,0,0,0,0,1],[0,0,1,0,0,0,1,0],[0,0,1,0,0,1,0,0],[0,0,0,1,1,0,0,0]]

 

def unvisited(x):

for v in range(N):

if visited[v] == 0 and Graphic[x][v] == 1:

return v

return -1

 

for v in range(N):

if visited[v] == 0:

print v

visited[v] = 1

stack.append(v)

while len(stack) > 0:

x = stack[-1]

w = unvisited(x)

if w != -1:

print w

visited[w] = 1

stack.append(w)

else:

stack.pop()

print

二、一些定理

运行时间:O(V+E),其中V是图中的顶点,E是图中的边。

定理一(括号定理):解释了图中任意两点u,v在深度优先搜索森林中可能的关系

a. u是v的后裔,则[d(u),f(u)]是[d(v),f(v)]的子区间

b.v是u的后裔,则[d(v),f(v)]是[d(u),f(u)]的子区间

c.u和v完全不相交,[d(u),f(u)]与[d(v),f(v)]不相关

三、回溯与剪枝:解答树的深度优先搜索

例子:八皇后问题

原文地址:https://www.cnblogs.com/zjgtan/p/3427923.html