# 基本的图算法：Swift实现

Cruise_Chan

## 预热

• 图 - Graph - G
• 顶点 - Vertex - V 一般用小写 u,v表示
• 边 - Edge - E
• 源顶点 - Source - S - s
• 目的顶点 - Destination - v
• 前驱 - Parent - π (点属性)
• 后继 - Successor (点属性)
• 距离 - Distance - d (点属性)

1. 结点未被发现 - whiteState
2. 结点被发现其邻接结点未被遍历完 - grayState
3. 结点被发现其邻接结点已经遍历完 - blackState

• 稀疏图：|E| << |V|^2 (<< 远小于)的图
• 稠密图：|E| ≈ |V|^2的图

• 深度优先搜索：DFS (Depth First Search)

## 广度优先搜索

### BFS伪代码

``````// 初始化
for each vertex u ∈ G.V - {s}
u.color = whiteState
u.d = ∞
u.π = NIL

// s置灰入（已搜索）队列
s.color = grayState
s.d = 0
s.π = NIL
Q = ∅
ENQUEUE(Q, s)

// 遍历开始
while Q != ∅
u = DEQUEUE(Q)
if v.color == whiteState
v.color = grayState
v.d = u.d + 1
v.π = u
ENQUQUE(Q, v)

// u的邻接结点已经遍历完成，标志为黑色
u.color = blackState
``````

### Swift实现

【注：感觉很渣，类的封装，没有实现迭代器，没有实现符号重载。。。待修改】

``````enum VertexState: Int {
case white = 0
case gray = 1
case black = 2
}

class Vertex {
var parent: Vertex?
var color: VertexState!
var distance: Int
var vIndex: Int

init (_ index: Int) {
self.vIndex = index
self.parent = nil
self.color = VertexState.white
self.distance = 100000
}
}

var queue: [Vertex] = []

}

class Graph {
var vertexArray: [Vertex]!

self.vertexArray = vertexArray
}
}

func BFS(inout graph: Graph, sourceVertex: Vertex) {

// sourceVertex置灰入队列
sourceVertex.color = VertexState.gray
sourceVertex.distance = 0
sourceVertex.parent = nil
queue.append(sourceVertex)

// 遍历
while queue.count > 0 {
var u = queue[0]
queue.removeAtIndex(0)

if v.color == VertexState.white {
v.color = VertexState.gray
v.distance = u.distance + 1
v.parent = u
queue.append(v)
}

u.color = VertexState.black
}
}
}

func printPath(g: Graph, s: Vertex, v: Vertex) {
if v.vIndex == s.vIndex {
print("\(s.vIndex)\t")
} else if v.parent == nil {
print("no path from s to v exists")
} else {
printPath(g, s, v.parent!)
print("\(v.vIndex)\t")
}
}

var vArray: [Vertex] = []

for var i = 0; i < 8; i++ {
var vertex: Vertex = Vertex(i)
vArray.append(vertex)
}

// TEST CASE

BFS(&g, vArray[0])
printPath(g, vArray[0], vArray[2])
``````

### 广度优先树

BFS在搜索的过程中也在创建一棵广度优先树。有如下定义：

## 深度优先搜索

1 <= u.d < u.f <= 2|V|

### DFS伪代码

DFS(G)

``````for each vertex u ∈ G.V
u.color = whiteState
u.π = NIL
time = 0   // 全局变量time
for each vertex u ∈ G.V
if u.color == whiteState
DFS-VISIT(G, u)
``````

DFS-VISIT(G, u)

``````time = time + 1
u.d = time
u.color = grayState
if v.color == whiteState
v.π = u
DFS-VISIT(G, v)
u.color = blackState
time = time + 1
u.f = time
``````

### Swift实现

``````var gTime = 0

enum VertexState: Int {
case white = 0
case gray = 1
case black = 2
}

class Vertex {
var discoverTime : Int
var finishTime: Int
var parent: Vertex?
var color: VertexState!
var distance: Int
var vIndex: Int

init (_ index: Int) {
self.discoverTime = 0
self.finishTime = 0
self.vIndex = index
self.parent = nil
self.color = VertexState.white
self.distance = 100000
}
}

var queue: [Vertex] = []

}

class Graph {
var vertexArray: [Vertex]!

self.vertexArray = vertexArray
}
}

func DFSVisit(inout graph: Graph, u: Vertex) {
gTime++
u.discoverTime = gTime
u.color = VertexState.gray

if v.color == VertexState.white {
v.parent = u
DFSVisit(&graph, v)
}
}

u.color = VertexState.black
gTime++
u.finishTime = gTime
}

func DFS(inout graph: Graph) {
for var i = 0; i < graph.vertexArray.count; i++ {
var u = graph.vertexArray[i]
if u.color == VertexState.white {
DFSVisit(&graph, u)
}
}
}

func printPath(g: Graph, s: Vertex, v: Vertex) {
if v.vIndex == s.vIndex {
print("\(s.vIndex)\t")
} else if v.parent == nil {
print("no path from s to v exists")
} else {
printPath(g, s, v.parent!)
print("\(v.vIndex)\t")
}
}

var vArray: [Vertex] = []

for var i = 0; i < 8; i++ {
var vertex: Vertex = Vertex(i)
vArray.append(vertex)
}

// TEST CASE

DFS(&g)

for var i = 0; i < vArray.count; i++ {
println("*******************")
println("\(i) node discover time is \(vArray[i].discoverTime)")
println("\(i) node finish time is \(vArray[i].finishTime)")
}
``````

## 拓扑排序

### 伪代码

TOPOLOGICAL-SORT(G)

``````    调用 DFS(G)计算每个结点v的完成时间v.f
当每个结点扫描结束的时候，将其插入到链表的前端
返回结点的链表
``````

P：

## 强连通分量

##### 青楼烟雨
self.blog = [note copy];

726 声望
69 粉丝
0 条评论