
์๋ ํ์ธ์ Foma ๐ป ์ ๋๋ค!
์ ๋ฒ ์๊ฐ์ ์ด์ง ํ์ ํธ๋ฆฌ๊ฐ ๋ญ์ง ์ด๋ก ์ ๋ํด ์์๋ณด์๋๋ฐ์.
์ค๋์ ์ด์ง ํ์ ํธ๋ฆฌ๋ฅผ ์ง์ ๊ตฌํํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
๋ฐ๋ก ์์ํ ๊ฒ์~
BSTNode
์ด์ง ํ์ ํธ๋ฆฌ์ ๋ ธ๋๋ฅผ ๋ง๋ค์ด ์ฃผ๊ฒ ์ต๋๋ค.
๋ ธ๋๋ ๊ฐ,์ผ์ชฝ,์ค๋ฅธ์ชฝ ์์์ ๋ ธ๋ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
class BSTNode<T:Comparable> {
var value:T
var leftChild:BSTNode?
var rightChild:BSTNode?
init(value:T) {
self.value = value
}
}
Binary Search Tree
์ด์ง ํ์ ํธ๋ฆฌ์ ์ต์๋จ ๊ฐ์ ๊ฐ์ง root๋ฅผ ํ๋กํผํฐ๋ก ์ ์ํ์ต๋๋ค.
struct BinarySearchTree<T:Comparable> {
var root:BSTNode<T>?
Insert
public mutating func insert(value:T) {
guard let _ = root else {
self.root = BSTNode(value: value)
return
}
var node:BSTNode = root!
while true {
if node.value > value {
if node.leftChild == nil {
node.leftChild = BSTNode(value: value)
break
}else {
node = node.leftChild!
}
}else {
if node.rightChild == nil {
node.rightChild = BSTNode(value: value)
break
}else {
node = node.rightChild!
}
}
}
}
๊ฐ์ด ์ ๋ค์ด๊ฐ๋์ง ํ ์คํธ ํด๋ด์ผ๊ฒ ์ฃ ?
ํ ์คํธ ํ๊ธฐ ์ํด์ ์๋์ ๊ฐ์ด ์ผ์ชฝ๊ณผ ์ค๋ฅธ์ชฝ ์์๋ค์ ์ฌ๊ทํ๋ฉฐ ์ถ๋ ฅํ๋ ๋ฉ์๋๋ฅผ ๊ตฌํํ์ต๋๋ค.
func printChild(node:BSTNode<Int>?) {
if node == nil { return }
print("\(node!.value)์ ์ผ์ชฝ ์์ :\(node!.leftChild?.value)")
print("\(node!.value)์ ์ค๋ฅธ์ชฝ ์์ :\(node!.rightChild?.value)")
printChild(node: node!.leftChild)
printChild(node: node!.rightChild)
}
10,11,8,1,3์ ์ฐจ๋ก๋ก ์ฝ์ ํ๊ณ ์ถ๋ ฅํด๋ณด๋ฉด ์๋์ ๊ฐ์ด ๊ฐ์ด ์ ๋ค์ด๊ฐ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
var bst = BinarySearchTree<Int>()
bst.insert(value: 10)
bst.insert(value: 11)
bst.insert(value: 8)
bst.insert(value: 1)
bst.insert(value: 3)
printChild(node: bst.root)
// 10์ ์ผ์ชฝ ์์ :Optional(8)
// 10์ ์ค๋ฅธ์ชฝ ์์ :Optional(11)
// 8์ ์ผ์ชฝ ์์ :Optional(1)
// 8์ ์ค๋ฅธ์ชฝ ์์ :nil
// 1์ ์ผ์ชฝ ์์ :nil
// 1์ ์ค๋ฅธ์ชฝ ์์ :Optional(3)
// 3์ ์ผ์ชฝ ์์ :nil
// 3์ ์ค๋ฅธ์ชฝ ์์ :nil
// 11์ ์ผ์ชฝ ์์ :nil
// 11์ ์ค๋ฅธ์ชฝ ์์ :nil
// 10
// 8 11
//1
// 3
Search
'์ด์ง ํ์ ํธ๋ฆฌ์ ๊ฒ์์ ์ด๋ค ๊ฑธ ๋ฐํํด์ผ ํ ๊น?' ๋ผ๊ณ ๊ณ ๋ฏผํ๋๋ฐ, ๋ณดํต ํด๋น ๊ฐ์ด ์๋์ง ์๋์ง๋ฅผ ๋ฐํํ๋๋ผ๊ตฌ์.
๊ทธ๋์ ์ ๋ Search๋ผ๋ ์ด๋ฆ ๋์ isContain์ผ๋ก ์ด๋ฆ์ง์ด์คฌ์ต๋๋ค.
public func isContain(value:T) -> Bool {
var node:BSTNode? = root
while node != nil {
if node!.value == value {
return true
}
node = node!.value > value ? node?.leftChild : node?.rightChild
}
return false
}
Insert์์ ์ฝ์ ํ ๊ฐ์ ํ ๋๋ก ๊ฒ์์ด ์ ๋๋์ง ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
์๋์ ๊ฐ์ด ํฌํจ๋์ด ์๋ค๋ฉด true๋ฅผ ๊ทธ๋ ์ง ์๋ค๋ฉด false๋ฅผ ๋ฐํํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
bst.isContain(value: 11) //true
bst.isContain(value: 100) //false
bst.isContain(value: 0) //false
bst.isContain(value: 8) //true
Delete
์ญ์ ๋ฅผ ๊ตฌํํ ๋ ์ง์ง ๋ณต์กํ์ต๋๋ค..
์์์ด ์์ ๋,1๊ฐ์ผ ๋,2๊ฐ์ผ ๋๋ฅผ ๋ชจ๋ ๋ฐ์ ธ์ค์ผ ํ์ต๋๋ค..
(์ฝ๋๊ฐ ์ ๋ง ๋ง์ ์๋ค์ง๋ง... ๋์ค์ ๋ฆฌํฉํฐ๋งํด์ ์์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค.)
public mutating func remove(value:T) {
if root == nil {
return
}
var parent:BSTNode = root!
var node:BSTNode? = root
while node != nil {
if node!.value == value {
//์์์ด 2๊ฐ ์์ ๋
if node?.leftChild != nil && node?.rightChild != nil {
let rightChild = node?.rightChild
node = findLeftChildMaxValue(node: node!.leftChild!)
node?.rightChild = rightChild
//์์์ด ์ผ์ชฝ๋ง ์์ ๋
}else if node?.leftChild != nil{
if node!.value < parent.value {
parent.leftChild = node?.leftChild
}else {
parent.rightChild = node?.leftChild
}
//์์์ด ์ค๋ฅธ์ชฝ๋ง ์์ ๋
}else if node?.rightChild != nil {
if node!.value < parent.value {
parent.leftChild = node?.rightChild
}else {
parent.rightChild = node?.rightChild
}
//์์์ด ์์ ๋
}else {
if node?.value == root?.value {
root = nil
return
}
if node!.value < parent.value {
parent.leftChild = nil
}else {
parent.rightChild = nil
}
}
if value == root?.value {
self.root = node!
}
break
}
parent = node!
node = node!.value > value ? node?.leftChild : node?.rightChild
}
}
์ฌ๊ธฐ์ ๋ง์ฝ ์์์ด 2๊ฐ๋ผ๋ฉด ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์์ ๊ฐ ๋๋ ์ผ์ชฝ ์์์ ๊ฐ์ฅ ํฐ ๊ฐ์ ๋์ฒดํด์ผ ํ๊ธฐ ๋๋ฌธ์
์๋๋ ์ค๋ฅธ์ชฝ ์์์ ๊ฐ์ฅ ์์ ๊ฐ์ ๊ตฌํ๋ ๋ฉ์๋์ด๊ณ ,
private func findRightChildMinValue(node:BSTNode<T>) -> BSTNode<T> {
var parent:BSTNode<T> = node
var leftChild:BSTNode? = node.leftChild
while leftChild?.leftChild != nil {
leftChild = leftChild?.leftChild!
parent = leftChild!
}
if leftChild?.rightChild != nil {
parent.rightChild = leftChild?.rightChild
}
return leftChild ?? parent
}
์๋๋ ์ผ์ชฝ ์์์ ๊ฐ์ฅ ํฐ ๊ฐ์ ๊ตฌํ๋ ๋ฉ์๋ ์ ๋๋ค.
private func findLeftChildMaxValue(node:BSTNode<T>) -> BSTNode<T> {
var parent:BSTNode<T> = node
var rightChild:BSTNode? = node.rightChild
while rightChild?.rightChild != nil {
rightChild = rightChild?.rightChild!
parent = rightChild!
}
if rightChild?.leftChild != nil {
parent.leftChild = rightChild?.leftChild
}
return rightChild ?? parent
}
์ญ์ ๋ํ Insert์์ ๋ฃ์ ๊ฐ์ผ๋ก ํ ์คํธ ํด๋ณด๊ฒ ์ต๋๋ค.
1. ์์์ด ์์ ๊ฒฝ์ฐ
๋จผ์ ์์์ด ์์ ๋์ ๊ฐ์ธ 3์ ์ญ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
์๋์ ๊ฐ์ด ์ ์์ ์ผ๋ก 3์ด ์ญ์ ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
bst.remove(value: 3)
printChild(node: bst.root)
// 10์ ์ผ์ชฝ ์์ :Optional(8)
// 10์ ์ค๋ฅธ์ชฝ ์์ :Optional(11)
// 8์ ์ผ์ชฝ ์์ :Optional(1)
// 8์ ์ค๋ฅธ์ชฝ ์์ :nil
// 1์ ์ผ์ชฝ ์์ :nil
// 1์ ์ค๋ฅธ์ชฝ ์์ :nil
// 11์ ์ผ์ชฝ ์์ :nil
// 11์ ์ค๋ฅธ์ชฝ ์์ :nil
// 10
// 8 11
//1
2. ์์์ด 1๊ฐ์ธ ๊ฒฝ์ฐ
๊ทธ ๋ค์์ผ๋ก ์์์ด 1๊ฐ์ธ ๊ฒฝ์ฐ์ธ 8์ ์ญ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์๋์ ๊ฐ์ด 8์ด ์ญ์ ๋๊ณ ๊ทธ ์๋ ์์์ผ๋ก ๋์ฒด๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
bst.remove(value: 8)
printChild(node: bst.root)
// 10์ ์ผ์ชฝ ์์ :Optional(1)
// 10์ ์ค๋ฅธ์ชฝ ์์ :Optional(11)
// 1์ ์ผ์ชฝ ์์ :nil
// 1์ ์ค๋ฅธ์ชฝ ์์ :Optional(3)
// 3์ ์ผ์ชฝ ์์ :nil
// 3์ ์ค๋ฅธ์ชฝ ์์ :nil
// 11์ ์ผ์ชฝ ์์ :nil
// 11์ ์ค๋ฅธ์ชฝ ์์ :nil
// 10
// 1 11
// 3
3. ์์์ด 2๊ฐ์ธ ๊ฒฝ์ฐ
๊ทธ ๋ค์์ผ๋ก ์์์ด 2๊ฐ์ธ ๊ฒฝ์ฐ์ธ 10์ ์ญ์ ํด๋ณด๊ฒ ์ต๋๋ค.
(์ ๋ ์ผ์ชฝ ์์ ์ค ๊ฐ์ฅ ํฐ ๊ฐ์ผ๋ก ๋์ฒดํ๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ต๋๋ค.)
์๋์ ๊ฐ์ด 10์ด ์ญ์ ๋๊ณ ์ผ์ชฝ ๊ฐ ์ค ๊ฐ์ฅ ํฐ ๊ฐ์ธ 8๋ก ๋์ฒด๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
bst.remove(value: 10)
printChild(node: bst.root)
// 8์ ์ผ์ชฝ ์์ :Optional(1)
// 8์ ์ค๋ฅธ์ชฝ ์์ :Optional(11)
// 1์ ์ผ์ชฝ ์์ :nil
// 1์ ์ค๋ฅธ์ชฝ ์์ :Optional(3)
// 3์ ์ผ์ชฝ ์์ :nil
// 3์ ์ค๋ฅธ์ชฝ ์์ :nil
// 11์ ์ผ์ชฝ ์์ :nil
// 11์ ์ค๋ฅธ์ชฝ ์์ :nil
// 8
// 1 11
// 3
๋๊ธ