개린이가 쓴 글이므로 오류가 있을 수 있음을 미리 알려드립니다 🐹 (꾸벅)
public class TreeNode<T> {
public var value: T // 노드 안의 값
public weak var parent: TreeNode? // 이 노드의 부모
public var children = [TreeNode<T>]() // 이 노드의 자식들
public init(value: T) {
self.value = value
}
public func addChild(_ node: TreeNode<T>) { // 자식노드 추가
children.append(node) // 자식 배열에 append
node.parent = self // 그 노드의 부모는 나다 !!!
}
}
아래의 extension을 통해 tree의 구조를 print 해볼 수 있습니다.
extension TreeNode: CustomStringConvertible {
public var description: String {
var s = "\(value)"
if !children.isEmpty {
s += " {" + children.map { $0.description }.joined(separator: ", ") + "}"
}
return s
}
}
public struct Vertex<T>: Equatable where T: Equatable, T: Hashable {
public var data: T
public let index: Int
}
public struct Edge<T>: Equatable where T: Equatable, T: Hashable {
public let from: Vertex<T>
public let to: Vertex<T>
public let weight: Double?
}
이제 그래프 코드를 보자 !!!
그래프를 구현하는 방식에는 2가지가 있다
두 개는 각각 장단점이 존재한다.
아래의 표를 통해 확인해보자
여기에서 V는 노드의 개수 / E는 간선의 개수이다.
연산 | 인접 리스트 | 인접 행렬 |
---|---|---|
공간 복잡도 | ||
노드 추가 | ||
간선 추가 | ||
연결 확인 |
인접리스트 장점
인접리스트 단점
인접 행렬의 장점
인접 행렬의 단점
인접 리스트는 그래프의 관계를 벡터 배열로 나타내는 방식
private class EdgeList<T> where T: Equatable, T: Hashable {
var vertex: Vertex<T>
var edges: [Edge<T>]? = nil
init(vertex: Vertex<T>) {
self.vertex = vertex
}
func addEdge(_ edge: Edge<T>) {
edges?.append(edge)
}
}
open override func createVertex(_ data: T) -> Vertex<T> {
// check if the vertex already exists
let matchingVertices = vertices.filter() { vertex in
return vertex.data == data
}
if matchingVertices.count > 0 {
return matchingVertices.last!
}
// if the vertex doesn't exist, create a new one
let vertex = Vertex(data: data, index: adjacencyList.count)
adjacencyList.append(EdgeList(vertex: vertex))
return vertex
}
인접 행렬은 그래프의 연결 관계를 이차원 배열로 나타내는 방법
private class EdgeList<T> where T: Equatable, T: Hashable {
var vertex: Vertex<T>
var edges: [Edge<T>]? = nil
init(vertex: Vertex<T>) {
self.vertex = vertex
}
func addEdge(_ edge: Edge<T>) {
edges?.append(edge)
}
}
open override func createVertex(_ data: T) -> Vertex<T> {
// check if the vertex already exists
let matchingVertices = vertices.filter() { vertex in
return vertex.data == data
}
if matchingVertices.count > 0 {
return matchingVertices.last!
}
// if the vertex doesn't exist, create a new one
let vertex = Vertex(data: data, index: adjacencyMatrix.count)
// Expand each existing row to the right one column.
for i in 0 ..< adjacencyMatrix.count {
adjacencyMatrix[i].append(nil)
}
// Add one new row at the bottom.
let newRow = [Double?](repeating: nil, count: adjacencyMatrix.count + 1)
adjacencyMatrix.append(newRow)
_vertices.append(vertex)
return vertex
}
+ 수정예정 ....
트리도 무향일 수 있답니다!
참고로 시간 복잡도 쓰실 때,
$
기호로 감싸주시면 수식 형태로 바뀌어서 좋아요!