์ž๋ฃŒ๊ตฌ์กฐ

[Swift] ์ž๋ฃŒ๊ตฌ์กฐ - ์ด์ง„ ํƒ์ƒ‰ํŠธ๋ฆฌ ( Binary Search Tree )

๊ฒฝํ‘ธ 2022. 5. 14. 21:33
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”~

 

์˜ค๋Š˜์€ ์ง€๋‚œ ํฌ์ŠคํŒ…(ํ•ด์‹œ ํ…Œ์ด๋ธ”)์— ์ด์–ด์„œ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค : )

 

[ ํ•ด์‹œ ํ…Œ์ด๋ธ” ํฌ์ŠคํŒ… ]

 

[Swift] ์ž๋ฃŒ๊ตฌ์กฐ - ํ•ด์‹œ ํ…Œ์ด๋ธ”(Hash Table)

์•ˆ๋…•ํ•˜์„ธ์œ ~ ์˜ค๋Š˜์€ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์— ์ด์–ด์„œ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณผ๊นŒํ•ฉ๋‹ˆ๋‹นใ…Žใ…Ž [Swift] ์ž๋ฃŒ๊ตฌ์กฐ - ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Linked List)(1) ์•ˆ๋…•ํ•˜์„ธ์œ ~ ์˜ค๋Š˜์€ ์ €๋ฒˆ ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋งํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ

pooh-footprints.tistory.com

 

 


 

 

์ผ๋‹จ, ํŠธ๋ฆฌ๋ถ€ํ„ฐ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

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์˜  ์ถœ์ฒ˜ ๊ทธ๋ฆฌ๊ณ  ์ฐธ๊ณ ํ•œ ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค : - )

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ‘ ๐Ÿ‘ ๐Ÿ‘

 

 

์ž๋ฃŒ๊ตฌ์กฐ - ํŠธ๋ฆฌ(Tree)๋ž€

ํŠธ๋ฆฌ๋ž€ - ๋…ธ๋“œ๋“ค์„ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐํ•œ ๊ณ„์ธตํ˜• ์ž๋ฃŒ๊ตฌ์กฐ - ์ œ์ผ์œ„์˜ ํ•˜๋‚˜์˜ ๋…ธ๋“œ๋ฅผ ๋ฃจํŠธ๋…ธ๋“œ๋กœ ํ•˜์—ฌ ๋‚˜๋จธ์ง€ ๋…ธ๋“œ๋“ค์ด ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ ๋จ - ํ•˜๋‚˜์˜ ๋…ธ๋“œ๋Š” ๊ทธ์ž์ฒด๋กœ ํŠธ๋ฆฌ์ด๋ฉฐ ๋ฃจํŠธ๊ฐ€ ๋œ๋‹ค ์šฉ์–ด 1. ๋…ธ

galid1.tistory.com

 

5 Gifs to Understand Binary Search Trees

Gif #1 Gif #2 : Binary Search Tree from Sorted Array  Gif #3 How insertion into a binary search tree (BST) works     Gif #4 : Degeneration of Binary Search Tree Demonstration   Gif #5 is coming ...  

blog.penjee.com

 

Swift) ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ(BST) ๊ตฌํ˜„ ํ•ด๋ณด๊ธฐ (1/2)

์•ˆ๋…•ํ•˜์„ธ์š”! ์†Œ๋“ค์ž…๋‹ˆ๋‹ค :) ์˜ค๋Š˜์€ ์ž๋ฃŒ๊ตฌ์กฐ์ด๊ธฐ๋„ ํ•˜๊ณ .. ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๊ธฐ๋„ ํ•œ.. (์•„๋ฆฌ์†ก) ํŠธ๋ฆฌ์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด๋ณผ ๊ฑฐ์˜ˆ์š”!!! ๊ทธ ์ค‘์— ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค!! ์Œ.. ์ง€๊ธˆ๊ป ๊ณต๋ถ€ํ•ด

babbab2.tistory.com

 

๋ฐ˜์‘ํ˜•