์๋ ํ์ธ์~
์ค๋์ ์ง๋ ํฌ์คํ (ํด์ ํ ์ด๋ธ)์ ์ด์ด์ ์ด์ง ํ์ ํธ๋ฆฌ์ ๋ํด์ ์์๋ณด๋ ค๊ณ ํฉ๋๋ค : )
[ ํด์ ํ ์ด๋ธ ํฌ์คํ ]
์ผ๋จ, ํธ๋ฆฌ๋ถํฐ ์์๋ณด๊ฒ ์ต๋๋ค.
1. ํธ๋ฆฌ๋
๋ ธ๋์ ๊ฐ์ ์ ์ด์ฉํด ์ฌ์ดํด์ ์ด๋ฃจ์ง ์๋๋ก ๋ง๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋งํฉ๋๋ค.
์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๊ฒฝ์ฐ
์ ํ์ผ๋ก Prev์ Next๋ฅผ ํตํด ์, ๋ค์ ์ฃผ์๋ฅผ ๊ฐ์ง๊ณ ์์์ง๋ง
ํธ๋ฆฌ์ ๊ฒฝ์ฐ
์ผ์ชฝ๊ณผ ์ค๋ฅธ์ชฝ์ ์์(child)์ด๋ผ๊ณ ํ๋ ๋ ธ๋๋ฅผ ๊ฐ์ง๊ณ ์๋
๋น์ ํ ๊ตฌ์กฐ์ ์๋ฃ๊ตฌ์กฐ์ ๋๋ค.
๋, ์ฌ์ดํด์ ์ด๋ฃจ์ง ์๊ณ ์๋๋ฐ ( J ↔๏ธ K )๊ฐ ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์
( F ↔๏ธ J ↔๏ธ K ) ์ด๋ฐ ์์ผ๋ก ์ํ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค๋ ๋ป์ ๋๋ค.
์ฉ์ด์ค๋ช
1. ๋ฃจํธ ๋ ธ๋(Root Node) : ํธ๋ฆฌ์ ๊ทผ๊ฐ์ด ๋๋ ๋ ธ๋์ ๋๋ค. ์ฆ, ์ต์์์ ์๋ ๋ ธ๋๋ฅผ ๋งํฉ๋๋ค.
2. ๋ถ๋ชจ ๋ ธ๋(Parent Node) :ํน์ ํ ๋ ธ๋์ ์์ ๋ ธ๋๋ฅผ ๋ถ๋ชจ ๋ ธ๋๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ์์์ B์ ๊ฒฝ์ฐ E์ F์ ๋ถ๋ชจ ๋ ธ๋๊ฐ ๋๋ ๊ฒ์ด์ฃ .
3. ์์ ๋ ธ๋(Child Node) : ํน์ ํ ๋ ธ๋์ ํ์ ๋ ธ๋๋ค์ ๋งํฉ๋๋ค. ๋ฌผ๋ก ์์ ์ด ๊ฐ๋ฆฌํค๊ณ ์๋ ๋ ธ๋์ ๋๋ค.
4. ๋ ๋ฒจ ( Level ) : ๋ ธ๋์ ๊น์ด, ๋ฃจํธ ๋ ธ๋์ ๋ ๋ฒจ์ 0์ด๊ณ ์ด๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ ๋ฒจ์ด 1์ฉ ์ฆ๊ฐํฉ๋๋ค.
5. ๋ฆฌํ ๋ ธ๋ ( Leaf Node ) : ์์ ๋ ธ๋๊ฐ ํ๋๋ ์๋ ๋ ธ๋๋ฅผ ๋งํฉ๋๋ค. ์ด๋ฏธ์ง์์๋ E, J, K, L, H, I๊ฐ ํด๋น๋ฉ๋๋ค.
6. ํธ๋ฆฌ์ ๊น์ด ( Depth ) : ์ต๋ ๋ ๋ฒจ์ ๊ฐ์ผ๋ก ์์์๋ 3์ด ๋๊ฒ ๋ค์.
2. ์ด์งํธ๋ฆฌ๋?
์์ ๋ ธ๋์ ๊ฐ์๊ฐ ๋ช ๊ฐ๋ ์๊ด์์ด ๊ฐ์ง ์ ์์ผ๋ฉฐ ์ด๋ ์์๋ ธ๋๋ฅผ ์ต๋ ๋ ๊ฐ๋ง ๊ฐ์ง๊ณ ์๋ ํธ๋ฆฌ๋ฅผ ์ด์งํธ๋ฆฌ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ์์ ์ด๋ฏธ์ง์ ์๋ ํธ๋ฆฌ๋ ์ด์งํธ๋ฆฌ๊ฐ ๋๊ฒ ๋ค์.
3. ์ด์ง ํ์ ํธ๋ฆฌ๋?
ํ์์ ๊ตญ์ด์ฌ์ ์ ๊ฒ์ํด ๋ณด๋ฉด "์ฌ๋ฌผ์ด๋ ํ์์ ๋ฐํ๊ธฐ ์ํด ์ฐพ์"์ด๋ผ๊ณ ๋์์๋๋ฐ
๋ง ๊ทธ๋๋ก ์ํ๋ ๊ฒ์ ์ฐพ๋ ํ์๋ฅผ ๋งํฉ๋๋ค.
์ํ๋ ๊ฒ์ ์ฐพ๊ธฐ ์ํด์๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์์ง๋ง ๊ฐ์ฅ ์ฌ์ด ๊ฒ ์ค ํ๋๊ฐ ๋น๊ตํด ๋ณด๋ ๊ฒ์ ๋๋ค.
๋ด๊ฐ ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ด 10์ด๋ผ๋ฉด
๋ค๋ฅธ ๊ฐ๋ค๊ณผ ๋น๊ตํด ํฐ์ง ์์์ง ํ์ธํด ๋๊ฐ๋ฉด ๊ฒฐ๊ตญ ์ฐพ๊ฒ ๋๋ ๊ฒ์ด์ฃ .
์ด์ง ํ์ ํธ๋ฆฌ์์๋ ํน์ ํ ์กฐ๊ฑด์ ๊ฐ์ถ๊ณ ์์ต๋๋ค.
1. ๋ชจ๋ ๋ ธ๋๊ฐ ์์ ์ ์ผ์ชฝ ์์ ๋ ธ๋์์๋ ์์ ๋ณด๋ค ์์ ๊ฐ์ด ์์ผ ํ๊ณ ์์ ์ ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋์๋ ์์ ๋ณด๋ค ํฐ ๊ฐ์ด ์์ผ ํฉ๋๋ค.
2. ๋ ธ๋์ ๊ฐ์ ์ ์ผํด์ผ ํ๋ค. ์ค๋ณต์ด ๋ถ๊ฐ๋ฅ.
3. ๋ ธ๋์ ๊ฐ์ ํญ์ ์กด์ฌํด์ผ ํ๋ค.
์์ 3๊ฐ์ง ๊ท์น์ ์ค์ํ๊ณ ์๋ค๋ฉด ์ด์ง ํ์ ํธ๋ฆฌ๋ผ๊ณ ํฉ๋๋ค.
์ดํด์ ๋์์ด ๋ ์ ์๊ฒ ์ ๋๋ฉ์ด์ ์ ํ๋ ๊ฐ์ง๊ณ ์๋ดค์ต๋๋ค.
4. ์ด์ง ํ์ ํธ๋ฆฌ ๊ตฌํ
์ฒซ ๋ฒ์งธ, ๋ ธ๋(Node) ํด๋์ค
// ์ ๋ค๋ฆญ์ Comparable๋ก ์ค์ ํ ๊ฒ์
// ์์์ ๋งํ ๊ฒ์ฒ๋ผ ๋ ๊ฐ์ ๋น๊ตํ ์ ์์ด์ผ
// ์์น๋ฅผ ์ ํ ์ ์๊ธฐ ๋๋ฌธ!
class Node<T: Comparable> {
var data: T
// ์์ ๋
ธ๋๊ฐ ์์ ์๋ ์์ ์๋ ์์ผ๋ ์ต์
๋!
var left: Node?
var right: Node?
init(data: T) {
self.data = data
}
}
๋ ๋ฒ์งธ, ์ด์ง ํ์ ํธ๋ฆฌ(BST) ํด๋์ค
class BinarySearchTree<T: Comparable> {
// ์์ ๋
ธ๋์ด์ ์ต์์ ๋
ธ๋!
var root: Node<T>?
}
์ธ ๋ฒ์งธ, ๋ฐ์ดํฐ ์ถ๊ฐ, ๊ฒ์, ์ญ์
๊ฐ์ฅ ๋จผ์ ์ถ๊ฐ์ ๋ํด์ ์์๋ณด๊ฒ ์ต๋๋ค.
๋ฐ์ดํฐ๋ฅผ ๋ฃ์ผ๋ ค๋ฉด ์์์ผ ํ๋ ๊ฒ์ด ๋ญ๊น์? ๋ฐ๋ก ์์น์ ๋๋ค.
๋ฐ๋ผ์ ํ์์ ์งํํ๊ณ ์ํ๋ ์์น๋ฅผ ๋ฐ๊ฒฌํ๋ค๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค.
func insert(data: T) {
// ๋ง์ฝ ๋ฃจํธ ๋
ธ๋๊ฐ ์๋ค๋ฉด?
// ๋ฐ๋ก ๋ค์ด์จ ๋
ธ๋๊ฐ ๋ฃจํธ ๋
ธ๋๊ฐ ๋์ผ๊ฒ ์ฃ ? ๐
guard let root = self.root else {
return self.root = Node.init(data: data)
}
var onNode = root // ๋ฃจํธ ๋
ธ๋๋ฅผ ๋ฐ์์ค๊ธฐ, ๋ฐ๋ก ์์ํ ์์น์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
// ํ์ ๋ฐ ์ถ๊ฐ
while true {
// ๋ค์ด์จ ๋ฐ์ดํฐ๊ฐ ํ์ฌ ๋
ธ๋๋ณด๋ค ์์ ๊ฒฝ์ฐ
if onNode.data > data {
// ์์ผ๋ฉด ์ผ์ชฝ
guard let nextNode = onNode.left else {
// ์ผ์ชฝ ๋
ธ๋๊ฐ ๋น์ด์๋ค๋ฉด ๋
ธ๋๋ฅผ ๊ทธ ์๋ฆฌ์ ์ถ๊ฐํด์ฃผ๊ธฐ
return onNode.left = Node.init(data: data)
}
// ๋น์ด์์ง ์๋ค๋ฉด ํ์ฌ ํ์์ ์ค์ฌ์ธ ๋
ธ๋๋ฅผ nextNode๋ก ๋ฐ๊พธ๊ณ ๋ค์ while๋ฌธ
onNode = nexNode
} else {
// ์๋ ๋ฐ๋
guard let nextNode = onNode.right esle {
return onNode.right = Node.init(data: data)
}
onNode = nextNode
}
}
}
๋ค์์ผ๋ก ํ์์ ์์๋ณด์ฃ .
// ํด๋น ๊ฐ์ ๋ ๋ฒจ๊ณผ ์กด์ฌํ๋์ง ๋ฐํํ๋ ํจ์๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค
func search(data: T) -> (Int?, Bool?) {
// ๋ง์ฝ์ ๋ฃจํธ๊ฐ nil์ด๋ฉด ๋น์ฐํ ํ์ํ ๊ฒ์ด ์์ต๋๋ค.
if root = nil { return (nil,nil) }
var onNode = root // ๋ฃจํธ๋ถํฐ ์์
var level = 0 // ๋ฃจํธ์ ๋ ๋ฒจ์ 0
while let node = onNode {
// ํด๋น๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ค๋ฉด ๋ ๋ฒจ๊ณผ true ๋ฐํ
if node.data == data {
return (level,true)
}
// ํ์ํ์ ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก
// ์ฐพ๊ณ ์ํ๋ ๋ฐ์ดํฐ์ ๊ฐ์ด ๋ ์์ผ๋ฉด ์ผ์ชฝ์ ์๋ค๋ ๊ฒ์ด๋ฏ๋ก ์ผ์ชฝ์ผ๋ก ๊ณ์ ์ด๋
if node.data > data {
onNode = node.left
} else {
onNode = node.right
}
// ์ผ์ชฝ์ผ๋ก ๋ด๋ ค๊ฐ๋ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ด๋ ค๊ฐ๋ level์ 1์ฉ ์ฆ๊ฐ
level += 1
}
return (nil,false)
}
๋ง์ง๋ง์ผ๋ก ์ญ์ ๋ฅผ ๊ตฌํํด ๋ด ์๋ค.
์ญ์ ์์๋ 3๊ฐ์ง ๊ฒฝ์ฐ์ ์๊ฐ ์กด์ฌํฉ๋๋ค.
1. ์์ ๋ ธ๋๊ฐ ์๋ ๋ ธ๋๋ฅผ ์ ๊ฑฐ
2. ์์ ๋ ธ๋๊ฐ ํ๋๋ง ์๋ ๋ ธ๋๋ฅผ ์ ๊ฑฐ
3. ์์ ๋ ธ๋๊ฐ ๋ ๊ฐ์ธ ๋ ธ๋๋ฅผ ์ ๊ฑฐ
์์ ๋ ธ๋๊ฐ ์๋ ๋ ธ๋๋ฅผ ์ ๊ฑฐ
// ์ญ์ ๊ฐ ์๋ฃ๋์๋์ง ํ์ธํ๊ธฐ ์ํด Bool ํ์
์ผ๋ก ๋ฐํ
func remove(data: T) -> Bool {
// ๋ฃจํธ๋ฅผ ์ฐพ์ ์ ์๋ค๋ฉด false
guard let root = self.root else { return false }
// ๋ฃจํธ๋
ธ๋๋ถํฐ ์์
var parentNode = root
var onNode: Node? = root
// ์ญ์ ํ ๋
ธ๋๋ฅผ ์ฐพ๊ธฐ
while let node = onNode {
// ๊ธฐ์กด์ ํ์์ฒ๋ผ ๋ ๊ฐ์ ๋น๊ตํ๋ฉด์ ์ฐพ๊ธฐ!
if node.data == data { break }
if node.data > data {
onNode = node.left
} else {
onNode = node.right
}
// ์ผ์ชฝ ํน์ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ด๋ ค๊ฐ ํด๋น ๋
ธ๋๋ฅผ ๋ถ๋ชจ ๋
ธ๋๋ก ๋๊ณ ๋ค์ ๋น๊ต
parentNode = node
}
// ์ฐพ๊ธฐ ์ฑ๊ณต
guard let deleteNode = onNode else {
// ์ฐพ๊ธฐ ์คํจ
return false
}
// ์์ ๋
ธ๋๊ฐ ๋ชจ๋ ์๋ค๋ฉด ( ์ญ์ ํ๋ ค๋ ๋
ธ๋์ ) ์ฐพ์ ์ํ
// ๋ฐ๋ผ์ ์ ๊ฑฐ
// ์ด๋, ์ ๊ฑฐํ๋ ค๋ ๋
ธ๋์ ๋ถ๋ชจ๋
ธ๋์ ์ผ์ชฝ์ธ์ง ์ค๋ฅธ์ชฝ์ธ์ง ํ์ธํ๊ณ ์ฐ๊ฒฐ์ ๋์ด์ค๋ค(nil)
if deleteNode.left == nil && deleteNode.right == nil {
if parentNode.data > data {
parentNode.left = nil
} else {
parentNode.right = nil
}
return true
}
}
์์ ๋ ธ๋๊ฐ ํ๋๋ง ์๋ ๋ ธ๋๋ฅผ ์ ๊ฑฐ
ํ์ํ๋ ๋ฐฉ๋ฒ์ ๊ฐ์ง๋ง ์กฐ๊ฑด์ด ๋ฌ๋ผ์ง๋๋ค.
// ์ ๊ฑฐํ๋ ค๋ ๋
ธ๋์ ์ผ์ชฝ ์์ ๋
ธ๋๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ
if (deleteNode.left != nil) && (deleteNode.right == nil) {
if parentNode.data > data {
// ๋ถ๋ชจ๋
ธ๋์ ๊ฐ์ ๋น๊ตํ๊ณ ๋ถ๋ชจ๋
ธ๋๊ฐ ๊ฐ์ด ํฌ๋ค๋ฉด
// ๋ถ๋ชจ๋
ธ๋์ ์ผ์ชฝ์ ์ ๊ฑฐํ๋ ค๋ ๋
ธ๋์ ์ผ์ชฝ ๋
ธ๋๋ฅผ ์ฐ๊ฒฐ
parentNode.left = deleteNode.left
} else {
// ์์ ๋ฐ
parentNode.right = deleteNode.left
}
return true
}
// ์ ๊ฑฐํ๋ ค๋ ๋
ธ๋์ ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ
if (deleteNode.left == nil) && (deleteNode.right != nil) {
if parentNode.data > data {
// ๋ถ๋ชจ๋
ธ๋์ ๊ฐ์ ๋น๊ตํ๊ณ ๋ถ๋ชจ๋
ธ๋๊ฐ ๊ฐ์ด ํฌ๋ค๋ฉด
// ๋ถ๋ชจ๋
ธ๋์ ์ผ์ชฝ์ ์ ๊ฑฐํ๋ ค๋ ๋
ธ๋์ ์ค๋ฅธ์ชฝ ๋
ธ๋๋ฅผ ์ฐ๊ฒฐ
parentNode.left = deleteNode.right
} else {
parentNode.right = deleteNode.right
}
return true
}
์์ ๋ ธ๋๊ฐ ๋ ๊ฐ์ธ ๋ ธ๋๋ฅผ ์ ๊ฑฐ
ํ๋จ์ ์๋ค๋ ๋ธ๋ก๊ทธ๊ฐ ์ ๋ง ์ ์ ๋ฆฌ๋์ด ์๊ณ ์ ๋ ์ฐธ๊ณ ํด์ ์ ๋ฆฌํ์ผ๋ ๊ผญ ๋ณด์๊ธธ ๋ฐ๋๋๋ค.
๋ฐฉ๋ฒ
1. ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋์์ ๊ฐ์ฅ ์์ ๊ฐ์ ์ฐพ์ ์ ๊ฑฐํ๋ ค๋ ๋ ธ๋์ ์์น๋ก ์ฎ๊ฒจ์ฃผ๋ ๋ฐฉ๋ฒ
2. ์ผ์ชฝ ์์ ๋ ธ๋์์ ๊ฐ์ฅ ํฐ ๊ฐ์ ์ฐพ์ ์ ๊ฑฐํ๋ ค๋ ๋ ธ๋์ ์์น๋ก ์ฎ๊ฒจ์ฃผ๋ ๋ฐฉ๋ฒ
ํด๋น ์ฝ๋๋ ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ๊ธฐ์ค์ผ๋ก ํ๊ณ ์์ต๋๋ค.
// ์ ๊ฑฐํ๊ณ ์ํ๋ ๋
ธ๋์ ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋๊ฐ ์กด์ฌ
guard let rightNode = deleteNode.right else { return false }
// ํ์์ ์ํ ๋ณ์ ์ธํ
var currentNode = rightNode
var currentParentNode = rightNode
// ํ์์ ํตํด ๊ฐ์ฅ ์์ ๊ฐ์ ์ฐพ๋ ๋ฃจํ ( ๊ณ์ ์ผ์ชฝ์ผ๋ก ๋ด๋ ค๊ฐ๊ธฐ )
while let nextNode = currentNode.left {
currentParentNode = currentNode
currentNode = nextNode
}
// ๋ง์ฝ์ ํ์ฌ ๋
ธ๋(๊ฐ์ฅ ์์ ๊ฐ์ ๊ฐ์ง)์ ์ค๋ฅธ์ชฝ ๋
ธ๋๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ ๊ธฐ์กด์ ๋ถ๋ชจ๋
ธ๋์ ์ฐ๊ฒฐ
if let currenteChildNode = currentNode.right {
currentParentNode.left = currentChildNode
// ์๊ธฐ ๋๋ฌธ์ ๋ถ๋ชจ ๋
ธ๋์ ์ผ์ชฝ ( ๊ธฐ์กด์ ์์ )์ nil ํด์ฃผ๊ธฐ
} else {
currentParentNode.left = nil
}
if parentNode.data > data {
parentNode.left = currentNode
} else {
parentNode.right = currentNode
}
currentNode.left = deleteNode.left
currentNode.right = deleteNode.right
return true
์ฌ์ฉํ ํธ๋ฆฌ ์ด๋ฏธ์ง์ ์ด์ง ํ์ ํธ๋ฆฌ gif์ ์ถ์ฒ ๊ทธ๋ฆฌ๊ณ ์ฐธ๊ณ ํ ๋ธ๋ก๊ทธ์ ๋๋ค : - )
๊ฐ์ฌํฉ๋๋ค ๐ ๐ ๐
'์๋ฃ๊ตฌ์กฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] ์๋ฃ๊ตฌ์กฐ - ํ(Heap) (0) | 2023.01.30 |
---|---|
[Swift] ์๋ฃ๊ตฌ์กฐ - ํด์ ํ ์ด๋ธ(Hash Table) (0) | 2022.04.21 |
[Swift] ์๋ฃ๊ตฌ์กฐ - ๋จ๋ฐฉํฅ / ์๋ฐฉํฅ ์ฐ๊ฒฐ ๋ฆฌ์คํธ(Linked List) (2) | 2022.04.20 |
[Swift] ์๋ฃ๊ตฌ์กฐ - ํ(Queue) (0) | 2022.04.19 |
[Swift] ์๋ฃ๊ตฌ์กฐ - ์คํ(Stack) (0) | 2022.04.18 |