트리 Tree
루트, 노드, 리프
add, search 메소드
class Node<T> {
var value: T
var children: [Node] = []
// 옵셔널인 이유: 모든 노드가 부모 노드를 갖고 있지 않기 때문이다(ex 루트),
// weak인 이유: 사이클을 피하기 위함이다 (컨벤션에 따르면 parent 객체가 child 객체를 strong하게 hold하는 것을 권장)
weak var parent: Node?
init(value: T) {
self.value = value
}
func add(child: Node) {
children.append(child)
child.parent = self
}
}
//A type that can be compared for value equality.
extension Node where T: Equatable {
func search(value: T) -> Node? {
// 1 현재 노드 체크
if value == self.value {
return self
}
// 2 자식 노드 배열 중 체크
for child in children {
if let found = child.search(value: value) {
return found
}
}
// 3 없을 때
return nil
}
}
let beverages = Node(value: "beverages")
let hotBeverages = Node(value: "hot")
let coldBeverages = Node(value: "cold")
let hotTea = Node(value: "tea")
let hotCoffee = Node(value: "coffee")
let hotCocoa = Node(value: "cocoa")
let coldSoda = Node(value: "soda")
let coldmilk = Node(value: "milk")
beverages.add(child: hotBeverages)
hotBeverages.add(child: hotTea)
hotBeverages.add(child: hotCoffee)
hotBeverages.add(child: hotCocoa)
beverages.add(child: coldBeverages)
coldBeverages.add(child: coldSoda)
coldBeverages.add(child: coldmilk)
extension Node: CustomStringConvertible {
var description: String { //프로토콜
var text = "\(value)"
if !children.isEmpty {
text += "{" + children.map{ $0.description }.joined(separator: ", ") + "}"
}
return text
}
}
print(beverages) //"beverages{hot{tea, coffee, cocoa}, cold{soda, milk}}\n"
beverages.search(value: "cocoa")
이진탐색트리의 균형잡힌 버전 O(logN)
https://velog.io/@msi753/이진-탐색-트리
이진탐색트리의 아래와 같은 문제(시간복잡도가 O(h))를 예방가능하다
a
\
b
\
c
\
d
블랙노드
의 개수는 같다node:
Tree: