mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-26 01:16:28 +08:00
refactor: extract Vertex and use Array<Vertex> (#374)
* refactor: extract Vertex and use Array<Vertex> * docs: add chapter to Package.swift * Update graph_adjacency_list.swift --------- Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
parent
85be0e286b
commit
04b0fb7455
3 changed files with 74 additions and 35 deletions
|
@ -5,14 +5,17 @@ import PackageDescription
|
||||||
let package = Package(
|
let package = Package(
|
||||||
name: "HelloAlgo",
|
name: "HelloAlgo",
|
||||||
products: [
|
products: [
|
||||||
|
// chapter_computational_complexity
|
||||||
.executable(name: "time_complexity", targets: ["time_complexity"]),
|
.executable(name: "time_complexity", targets: ["time_complexity"]),
|
||||||
.executable(name: "worst_best_time_complexity", targets: ["worst_best_time_complexity"]),
|
.executable(name: "worst_best_time_complexity", targets: ["worst_best_time_complexity"]),
|
||||||
.executable(name: "space_complexity", targets: ["space_complexity"]),
|
.executable(name: "space_complexity", targets: ["space_complexity"]),
|
||||||
.executable(name: "leetcode_two_sum", targets: ["leetcode_two_sum"]),
|
.executable(name: "leetcode_two_sum", targets: ["leetcode_two_sum"]),
|
||||||
|
// chapter_array_and_linkedlist
|
||||||
.executable(name: "array", targets: ["array"]),
|
.executable(name: "array", targets: ["array"]),
|
||||||
.executable(name: "linked_list", targets: ["linked_list"]),
|
.executable(name: "linked_list", targets: ["linked_list"]),
|
||||||
.executable(name: "list", targets: ["list"]),
|
.executable(name: "list", targets: ["list"]),
|
||||||
.executable(name: "my_list", targets: ["my_list"]),
|
.executable(name: "my_list", targets: ["my_list"]),
|
||||||
|
// chapter_stack_and_queue
|
||||||
.executable(name: "stack", targets: ["stack"]),
|
.executable(name: "stack", targets: ["stack"]),
|
||||||
.executable(name: "linkedlist_stack", targets: ["linkedlist_stack"]),
|
.executable(name: "linkedlist_stack", targets: ["linkedlist_stack"]),
|
||||||
.executable(name: "array_stack", targets: ["array_stack"]),
|
.executable(name: "array_stack", targets: ["array_stack"]),
|
||||||
|
@ -20,19 +23,25 @@ let package = Package(
|
||||||
.executable(name: "linkedlist_queue", targets: ["linkedlist_queue"]),
|
.executable(name: "linkedlist_queue", targets: ["linkedlist_queue"]),
|
||||||
.executable(name: "array_queue", targets: ["array_queue"]),
|
.executable(name: "array_queue", targets: ["array_queue"]),
|
||||||
.executable(name: "deque", targets: ["deque"]),
|
.executable(name: "deque", targets: ["deque"]),
|
||||||
|
// chapter_hashing
|
||||||
.executable(name: "hash_map", targets: ["hash_map"]),
|
.executable(name: "hash_map", targets: ["hash_map"]),
|
||||||
.executable(name: "array_hash_map", targets: ["array_hash_map"]),
|
.executable(name: "array_hash_map", targets: ["array_hash_map"]),
|
||||||
|
// chapter_tree
|
||||||
.executable(name: "binary_tree", targets: ["binary_tree"]),
|
.executable(name: "binary_tree", targets: ["binary_tree"]),
|
||||||
.executable(name: "binary_tree_bfs", targets: ["binary_tree_bfs"]),
|
.executable(name: "binary_tree_bfs", targets: ["binary_tree_bfs"]),
|
||||||
.executable(name: "binary_tree_dfs", targets: ["binary_tree_dfs"]),
|
.executable(name: "binary_tree_dfs", targets: ["binary_tree_dfs"]),
|
||||||
.executable(name: "binary_search_tree", targets: ["binary_search_tree"]),
|
.executable(name: "binary_search_tree", targets: ["binary_search_tree"]),
|
||||||
.executable(name: "avl_tree", targets: ["avl_tree"]),
|
.executable(name: "avl_tree", targets: ["avl_tree"]),
|
||||||
|
// chapter_heap
|
||||||
.executable(name: "my_heap", targets: ["my_heap"]),
|
.executable(name: "my_heap", targets: ["my_heap"]),
|
||||||
|
// chapter_graph
|
||||||
.executable(name: "graph_adjacency_matrix", targets: ["graph_adjacency_matrix"]),
|
.executable(name: "graph_adjacency_matrix", targets: ["graph_adjacency_matrix"]),
|
||||||
.executable(name: "graph_adjacency_list", targets: ["graph_adjacency_list"]),
|
.executable(name: "graph_adjacency_list", targets: ["graph_adjacency_list"]),
|
||||||
|
// chapter_searching
|
||||||
.executable(name: "linear_search", targets: ["linear_search"]),
|
.executable(name: "linear_search", targets: ["linear_search"]),
|
||||||
.executable(name: "binary_search", targets: ["binary_search"]),
|
.executable(name: "binary_search", targets: ["binary_search"]),
|
||||||
.executable(name: "hashing_search", targets: ["hashing_search"]),
|
.executable(name: "hashing_search", targets: ["hashing_search"]),
|
||||||
|
// chapter_sorting
|
||||||
.executable(name: "bubble_sort", targets: ["bubble_sort"]),
|
.executable(name: "bubble_sort", targets: ["bubble_sort"]),
|
||||||
.executable(name: "insertion_sort", targets: ["insertion_sort"]),
|
.executable(name: "insertion_sort", targets: ["insertion_sort"]),
|
||||||
.executable(name: "quick_sort", targets: ["quick_sort"]),
|
.executable(name: "quick_sort", targets: ["quick_sort"]),
|
||||||
|
@ -41,14 +50,17 @@ let package = Package(
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(name: "utils", path: "utils"),
|
.target(name: "utils", path: "utils"),
|
||||||
|
// chapter_computational_complexity
|
||||||
.executableTarget(name: "time_complexity", path: "chapter_computational_complexity", sources: ["time_complexity.swift"]),
|
.executableTarget(name: "time_complexity", path: "chapter_computational_complexity", sources: ["time_complexity.swift"]),
|
||||||
.executableTarget(name: "worst_best_time_complexity", path: "chapter_computational_complexity", sources: ["worst_best_time_complexity.swift"]),
|
.executableTarget(name: "worst_best_time_complexity", path: "chapter_computational_complexity", sources: ["worst_best_time_complexity.swift"]),
|
||||||
.executableTarget(name: "space_complexity", dependencies: ["utils"], path: "chapter_computational_complexity", sources: ["space_complexity.swift"]),
|
.executableTarget(name: "space_complexity", dependencies: ["utils"], path: "chapter_computational_complexity", sources: ["space_complexity.swift"]),
|
||||||
.executableTarget(name: "leetcode_two_sum", path: "chapter_computational_complexity", sources: ["leetcode_two_sum.swift"]),
|
.executableTarget(name: "leetcode_two_sum", path: "chapter_computational_complexity", sources: ["leetcode_two_sum.swift"]),
|
||||||
|
// chapter_array_and_linkedlist
|
||||||
.executableTarget(name: "array", path: "chapter_array_and_linkedlist", sources: ["array.swift"]),
|
.executableTarget(name: "array", path: "chapter_array_and_linkedlist", sources: ["array.swift"]),
|
||||||
.executableTarget(name: "linked_list", dependencies: ["utils"], path: "chapter_array_and_linkedlist", sources: ["linked_list.swift"]),
|
.executableTarget(name: "linked_list", dependencies: ["utils"], path: "chapter_array_and_linkedlist", sources: ["linked_list.swift"]),
|
||||||
.executableTarget(name: "list", path: "chapter_array_and_linkedlist", sources: ["list.swift"]),
|
.executableTarget(name: "list", path: "chapter_array_and_linkedlist", sources: ["list.swift"]),
|
||||||
.executableTarget(name: "my_list", path: "chapter_array_and_linkedlist", sources: ["my_list.swift"]),
|
.executableTarget(name: "my_list", path: "chapter_array_and_linkedlist", sources: ["my_list.swift"]),
|
||||||
|
// chapter_stack_and_queue
|
||||||
.executableTarget(name: "stack", path: "chapter_stack_and_queue", sources: ["stack.swift"]),
|
.executableTarget(name: "stack", path: "chapter_stack_and_queue", sources: ["stack.swift"]),
|
||||||
.executableTarget(name: "linkedlist_stack", dependencies: ["utils"], path: "chapter_stack_and_queue", sources: ["linkedlist_stack.swift"]),
|
.executableTarget(name: "linkedlist_stack", dependencies: ["utils"], path: "chapter_stack_and_queue", sources: ["linkedlist_stack.swift"]),
|
||||||
.executableTarget(name: "array_stack", path: "chapter_stack_and_queue", sources: ["array_stack.swift"]),
|
.executableTarget(name: "array_stack", path: "chapter_stack_and_queue", sources: ["array_stack.swift"]),
|
||||||
|
@ -56,19 +68,25 @@ let package = Package(
|
||||||
.executableTarget(name: "linkedlist_queue", dependencies: ["utils"], path: "chapter_stack_and_queue", sources: ["linkedlist_queue.swift"]),
|
.executableTarget(name: "linkedlist_queue", dependencies: ["utils"], path: "chapter_stack_and_queue", sources: ["linkedlist_queue.swift"]),
|
||||||
.executableTarget(name: "array_queue", path: "chapter_stack_and_queue", sources: ["array_queue.swift"]),
|
.executableTarget(name: "array_queue", path: "chapter_stack_and_queue", sources: ["array_queue.swift"]),
|
||||||
.executableTarget(name: "deque", path: "chapter_stack_and_queue", sources: ["deque.swift"]),
|
.executableTarget(name: "deque", path: "chapter_stack_and_queue", sources: ["deque.swift"]),
|
||||||
|
// chapter_hashing
|
||||||
.executableTarget(name: "hash_map", dependencies: ["utils"], path: "chapter_hashing", sources: ["hash_map.swift"]),
|
.executableTarget(name: "hash_map", dependencies: ["utils"], path: "chapter_hashing", sources: ["hash_map.swift"]),
|
||||||
.executableTarget(name: "array_hash_map", path: "chapter_hashing", sources: ["array_hash_map.swift"]),
|
.executableTarget(name: "array_hash_map", path: "chapter_hashing", sources: ["array_hash_map.swift"]),
|
||||||
|
// chapter_tree
|
||||||
.executableTarget(name: "binary_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree.swift"]),
|
.executableTarget(name: "binary_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree.swift"]),
|
||||||
.executableTarget(name: "binary_tree_bfs", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree_bfs.swift"]),
|
.executableTarget(name: "binary_tree_bfs", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree_bfs.swift"]),
|
||||||
.executableTarget(name: "binary_tree_dfs", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree_dfs.swift"]),
|
.executableTarget(name: "binary_tree_dfs", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree_dfs.swift"]),
|
||||||
.executableTarget(name: "binary_search_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_search_tree.swift"]),
|
.executableTarget(name: "binary_search_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_search_tree.swift"]),
|
||||||
.executableTarget(name: "avl_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["avl_tree.swift"]),
|
.executableTarget(name: "avl_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["avl_tree.swift"]),
|
||||||
|
// chapter_heap
|
||||||
.executableTarget(name: "my_heap", dependencies: ["utils"], path: "chapter_heap", sources: ["my_heap.swift"]),
|
.executableTarget(name: "my_heap", dependencies: ["utils"], path: "chapter_heap", sources: ["my_heap.swift"]),
|
||||||
|
// chapter_graph
|
||||||
.executableTarget(name: "graph_adjacency_matrix", dependencies: ["utils"], path: "chapter_graph", sources: ["graph_adjacency_matrix.swift"]),
|
.executableTarget(name: "graph_adjacency_matrix", dependencies: ["utils"], path: "chapter_graph", sources: ["graph_adjacency_matrix.swift"]),
|
||||||
.executableTarget(name: "graph_adjacency_list", path: "chapter_graph", sources: ["graph_adjacency_list.swift"]),
|
.executableTarget(name: "graph_adjacency_list", dependencies: ["utils"], path: "chapter_graph", sources: ["graph_adjacency_list.swift"]),
|
||||||
|
// chapter_searching
|
||||||
.executableTarget(name: "linear_search", dependencies: ["utils"], path: "chapter_searching", sources: ["linear_search.swift"]),
|
.executableTarget(name: "linear_search", dependencies: ["utils"], path: "chapter_searching", sources: ["linear_search.swift"]),
|
||||||
.executableTarget(name: "binary_search", path: "chapter_searching", sources: ["binary_search.swift"]),
|
.executableTarget(name: "binary_search", path: "chapter_searching", sources: ["binary_search.swift"]),
|
||||||
.executableTarget(name: "hashing_search", dependencies: ["utils"], path: "chapter_searching", sources: ["hashing_search.swift"]),
|
.executableTarget(name: "hashing_search", dependencies: ["utils"], path: "chapter_searching", sources: ["hashing_search.swift"]),
|
||||||
|
// chapter_sorting
|
||||||
.executableTarget(name: "bubble_sort", path: "chapter_sorting", sources: ["bubble_sort.swift"]),
|
.executableTarget(name: "bubble_sort", path: "chapter_sorting", sources: ["bubble_sort.swift"]),
|
||||||
.executableTarget(name: "insertion_sort", path: "chapter_sorting", sources: ["insertion_sort.swift"]),
|
.executableTarget(name: "insertion_sort", path: "chapter_sorting", sources: ["insertion_sort.swift"]),
|
||||||
.executableTarget(name: "quick_sort", path: "chapter_sorting", sources: ["quick_sort.swift"]),
|
.executableTarget(name: "quick_sort", path: "chapter_sorting", sources: ["quick_sort.swift"]),
|
||||||
|
|
|
@ -4,28 +4,13 @@
|
||||||
* Author: nuomi1 (nuomi1@qq.com)
|
* Author: nuomi1 (nuomi1@qq.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 顶点类 */
|
import utils
|
||||||
class Vertex: Hashable {
|
|
||||||
var val: Int
|
|
||||||
|
|
||||||
init(val: Int) {
|
|
||||||
self.val = val
|
|
||||||
}
|
|
||||||
|
|
||||||
static func == (lhs: Vertex, rhs: Vertex) -> Bool {
|
|
||||||
lhs.val == rhs.val
|
|
||||||
}
|
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
|
||||||
hasher.combine(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 基于邻接表实现的无向图类 */
|
/* 基于邻接表实现的无向图类 */
|
||||||
class GraphAdjList {
|
class GraphAdjList {
|
||||||
// 邻接表,使用哈希表来代替链表,以提升删除边、删除顶点的效率
|
// 邻接表,使用哈希表来代替链表,以提升删除边、删除顶点的效率
|
||||||
// 请注意,adjList 中的元素是 Vertex 对象
|
// 请注意,adjList 中的元素是 Vertex 对象
|
||||||
private var adjList: [Vertex: Set<Vertex>]
|
private var adjList: [Vertex: [Vertex]]
|
||||||
|
|
||||||
/* 构造方法 */
|
/* 构造方法 */
|
||||||
init(edges: [[Vertex]]) {
|
init(edges: [[Vertex]]) {
|
||||||
|
@ -49,8 +34,8 @@ class GraphAdjList {
|
||||||
fatalError("参数错误")
|
fatalError("参数错误")
|
||||||
}
|
}
|
||||||
// 添加边 vet1 - vet2
|
// 添加边 vet1 - vet2
|
||||||
adjList[vet1]?.insert(vet2)
|
adjList[vet1]?.append(vet2)
|
||||||
adjList[vet2]?.insert(vet1)
|
adjList[vet2]?.append(vet1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 删除边 */
|
/* 删除边 */
|
||||||
|
@ -59,8 +44,8 @@ class GraphAdjList {
|
||||||
fatalError("参数错误")
|
fatalError("参数错误")
|
||||||
}
|
}
|
||||||
// 删除边 vet1 - vet2
|
// 删除边 vet1 - vet2
|
||||||
adjList[vet1]?.remove(vet2)
|
adjList[vet1]?.removeAll(where: { $0 == vet2 })
|
||||||
adjList[vet2]?.remove(vet1)
|
adjList[vet2]?.removeAll(where: { $0 == vet1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 添加顶点 */
|
/* 添加顶点 */
|
||||||
|
@ -81,7 +66,7 @@ class GraphAdjList {
|
||||||
adjList.removeValue(forKey: vet)
|
adjList.removeValue(forKey: vet)
|
||||||
// 遍历其它顶点的链表,删除所有包含 vet 的边
|
// 遍历其它顶点的链表,删除所有包含 vet 的边
|
||||||
for key in adjList.keys {
|
for key in adjList.keys {
|
||||||
adjList[key]?.remove(vet)
|
adjList[key]?.removeAll(where: { $0 == vet })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,25 +88,21 @@ enum GraphAdjacencyList {
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
static func main() {
|
static func main() {
|
||||||
/* 初始化无向图 */
|
/* 初始化无向图 */
|
||||||
let v0 = Vertex(val: 1)
|
let v = Vertex.valsToVets([1, 3, 2, 5, 4])
|
||||||
let v1 = Vertex(val: 3)
|
let edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]], [v[2], v[3]], [v[2], v[4]], [v[3], v[4]]]
|
||||||
let v2 = Vertex(val: 2)
|
|
||||||
let v3 = Vertex(val: 5)
|
|
||||||
let v4 = Vertex(val: 4)
|
|
||||||
let edges = [[v0, v1], [v1, v2], [v2, v3], [v0, v3], [v2, v4], [v3, v4]]
|
|
||||||
let graph = GraphAdjList(edges: edges)
|
let graph = GraphAdjList(edges: edges)
|
||||||
print("\n初始化后,图为")
|
print("\n初始化后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
/* 添加边 */
|
/* 添加边 */
|
||||||
// 顶点 1, 2 即 v0, v2
|
// 顶点 1, 2 即 v[0], v[2]
|
||||||
graph.addEdge(vet1: v0, vet2: v2)
|
graph.addEdge(vet1: v[0], vet2: v[2])
|
||||||
print("\n添加边 1-2 后,图为")
|
print("\n添加边 1-2 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
/* 删除边 */
|
/* 删除边 */
|
||||||
// 顶点 1, 3 即 v0, v1
|
// 顶点 1, 3 即 v[0], v[1]
|
||||||
graph.removeEdge(vet1: v0, vet2: v1)
|
graph.removeEdge(vet1: v[0], vet2: v[1])
|
||||||
print("\n删除边 1-3 后,图为")
|
print("\n删除边 1-3 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
|
@ -132,8 +113,8 @@ enum GraphAdjacencyList {
|
||||||
graph.print()
|
graph.print()
|
||||||
|
|
||||||
/* 删除顶点 */
|
/* 删除顶点 */
|
||||||
// 顶点 3 即 v1
|
// 顶点 3 即 v[1]
|
||||||
graph.removeVertex(vet: v1)
|
graph.removeVertex(vet: v[1])
|
||||||
print("\n删除顶点 3 后,图为")
|
print("\n删除顶点 3 后,图为")
|
||||||
graph.print()
|
graph.print()
|
||||||
}
|
}
|
||||||
|
|
40
codes/swift/utils/Vertex.swift
Normal file
40
codes/swift/utils/Vertex.swift
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* File: Vertex.swift
|
||||||
|
* Created Time: 2023-02-19
|
||||||
|
* Author: nuomi1 (nuomi1@qq.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 顶点类 */
|
||||||
|
public class Vertex: Hashable {
|
||||||
|
public var val: Int
|
||||||
|
|
||||||
|
public init(val: Int) {
|
||||||
|
self.val = val
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func == (lhs: Vertex, rhs: Vertex) -> Bool {
|
||||||
|
lhs.val == rhs.val
|
||||||
|
}
|
||||||
|
|
||||||
|
public func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入值列表 vals ,返回顶点列表 vets */
|
||||||
|
public static func valsToVets(_ vals: [Int]) -> [Vertex] {
|
||||||
|
var vets: [Vertex] = []
|
||||||
|
for val in vals {
|
||||||
|
vets.append(Vertex(val: val))
|
||||||
|
}
|
||||||
|
return vets
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入顶点列表 vets ,返回值列表 vals */
|
||||||
|
public static func vetsToVals(_ vets: [Vertex]) -> [Int] {
|
||||||
|
var vals: [Int] = []
|
||||||
|
for vet in vets {
|
||||||
|
vals.append(vet.val)
|
||||||
|
}
|
||||||
|
return vals
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue