learnings/Algorithm&DS

[DataStructure] ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋ฅผ Swift๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ

Une. 2024. 3. 20. 19:57

https://m.hanbit.co.kr/store/books/book_view.html?p_code=B3450156021
์ด ๊ธ€์€ ์ฑ… '๋‡Œ๋ฅผ ์ž๊ทนํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜' ์—์„œ ๋ฐฐ์šด ๋‚ด์šฉ์„ ์ ๊ทน ์ฐธ๊ณ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ, ๋ชจ๋“  ์ž๋ฃŒ๊ตฌ์กฐ ๋ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ Swift๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Œ์„ ๋จผ์ € ์•Œ๋ฆฝ๋‹ˆ๋‹ค.

 

๋‡Œ๋ฅผ ์ž๊ทนํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ์ž๋ฃŒ๊ตฌ์กฐ, ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์‚ฐ๊ณผ ๊ฐ™๋‹ค. ๋„˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ธฐ์— ์˜ค๋ฅด๊ณ  ๋˜ ์˜ค๋ฅด์ง€๋งŒ, ์ •์ƒ์„ ๋ฐŸ๊ธฐ๋ž€ ์‰ฝ์ง€ ์•Š๋‹ค. ๋ฐฐ์šฐ๊ธฐ๊ฐ€ ์–ด๋ ต๊ณ  ์žฌ๋ฏธ๋„ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋งŽ์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€

m.hanbit.co.kr

 

0. ์„œ๋ก 
๋ฐฐ์—ด์„ ์•Œ๊ณ  ๊ณ„์‹ ๊ฐ€์š”?
๊ฐ™์€ ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์—ฐ์†์ ์œผ๋กœ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
๋ฉ”๋ชจ๋ฆฌ์— ์—ฐ์†์ ์œผ๋กœ ์ €์žฅ๋˜์–ด ์žˆ๋‹ค๋Š” ํŠน์ง•์œผ๋กœ ์ธํ•ด ๋น ๋ฅธ ์ ‘๊ทผ์†๋„์— ๊ฐ•์ ์„ ๊ฐ€์ง€๋Š”๊ฒƒ์ด ํŠน์ง•์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜, ์ดˆ๊ธฐ์— ํ• ๋‹นํ•œ ํฌ๊ธฐ ๋งŒํผ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋ฅผ ๋„˜์–ด์„œ๋Š” ํฌ๊ธฐ์˜ ์ž๋ฃŒ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด์„ 
๋” ํฐ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์ฃผ์‹œํ‚ค๋Š” ๋“ฑ ์ถ”๊ฐ€์ ์ธ ์ž‘์—…์ด ํ•„์š”ํ•œ ๊ฒƒ ๋˜ํ•œ ํŠน์ง•์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด, ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ์†์ ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉด์„œ๋„, ๋ฐ์ดํ„ฐ ์ด์ฃผ๋“ฑ์˜ ๋ฒˆ๊ฑฐ๋กœ์šด ์ž‘์—…์—์„œ ๋ฒ—์–ด๋‚  ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ์—†์„๊นŒ์š”?
๋‹ค ์•Œ๊ณ  ๊ณ„์‹œ๊ฒ ์ง€๋งŒ, ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋Š” ์ด์— ์ ํ•ฉํ•œ ์ž๋ฃŒ๊ตฌ์กฐ ์ž…๋‹ˆ๋‹ค.
ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ์— ๋‹ค์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ์–ด, ๊ณ„์†ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ผฌ๋ฆฌ์— ๊ผฌ๋ฆฌ๋ฅผ ๋ฌด๋Š” ๋ชจ์Šต์œผ๋กœ ์ฃผ๋ ์ฃผ๋  ๋‹ฌ ์ˆ˜ ์žˆ์ฃ .

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ์†Œ๊ฐœ๋Š” ์ด์ฏค ๋๋‚ด๊ณ , ์ด์—๋Œ€ํ•œ ๊ตฌํ˜„์„ ๊ตฌ์กฐ์ •์˜-์‚ฝ์ž…-ํƒ์ƒ‰-์‚ญ์ œ ์ˆœ์œผ๋กœ ์ง„ํ–‰ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ๊ตฌ์กฐ ์ •์˜

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋Š” ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ์ž๋ฃŒ์— ๋Œ€ํ•œ ์œ„์น˜์ •๋ณด๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฉ์–ด๋ฆฌ๊ฐ€, ์—ฌ๋Ÿฌ ๊ผฌ๋ฆฌ๋ฅผ ๋ฌผ์–ด ์ฃผ๋ ์ฃผ๋  ๋‹ฌ๋ ค์žˆ๋Š” ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์ด ๋ฉ์–ด๋ฆฌ๋ฅผ '๋…ธ๋“œ' ๋ผ๊ณ  ๋ถ€๋ฅด๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•ด๋ณด๋„๋ก ํ•˜์ฃ .

class Node<T>{
    var data:T?
    var nextNode:Node<T>?
    init(data: T? = nil, nextNode: Node<T>? = nil) {
        self.data = data
        self.nextNode = nextNode
    }
    deinit{   
    }
}

 

์ œ๋„ค๋ฆญ์„ ๋ชจ๋ฅด์‹œ๋Š” ๋ถ„์€ Swift-์ œ๋„ค๋ฆญ์„ ๊ณต๋ถ€ํ•˜๊ณ  ์˜ค์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.
๋…ธ๋“œ๋Š” ๋ฐ์ดํ„ฐ์™€ ๋‹ค์Œ ๋…ธ๋“œ์˜ ์œ„์น˜๋ฅผ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋ฉค๋ฒ„๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค.
์ด์ œ ์ด๋ฅผ ์ค„์ค„์ด ์—ฎ์–ด๋ณผ๊นŒ์š”?
๋น„์—”๋‚˜ ์†Œ์„ธ์ง€์—๋„ ์ฒ˜์Œ ์†Œ์„ธ์ง€๊ฐ€ ์žˆ๊ธฐ ๋งˆ๋ จ์ด๋‹ˆ, ์ด๊ฒƒ์„ ๋จธ๋ฆฌ๋ผ๊ณ  ํ•ด ๋‘˜๊นŒ์š”.
๋” ์ƒ๊ฐํ•  ํ•„์š” ์—†์ด, ์ง€๊ธˆ๊นŒ์ง€ ๋งํ•œ ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

class SingleLinkedList<T>{
    var head: Node<T>?
}

์ž, head(๋จธ๋ฆฌ)๋ฅผ ๊ฐ€์ง„ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์™„์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!
์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ์›ํ•˜๋Š” ๋งŒํผ ์ž๋ฃŒ๋“ค์„ ๋ชจ์•„ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค!
๊ทธ๋Ÿฐ๋ฐ, ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ์“ฐ๋ƒ๊ณ ์š”?
๋‹คํ–‰์ž…๋‹ˆ๋‹ค. ์–ด๋””์— ์จ์•ผํ•˜๋Š”์ง€ ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๋‹จํ•œ ์งˆ๋ฌธ์ด๊ตฐ์š”. ์ฐจ๊ทผ์ฐจ๊ทผ ์•Œ์•„๊ฐ€๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.

2. ์‚ฝ์ž…

๊ธฐ์ฐจ๋†€์ด๋ฅผ ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค.
์ด๋ฏธ ๊ธฐ์ฐจ๋†€์ด๋ฅผ ํ•˜๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ์„ ํ•˜๋‚˜ ๋” ๋Š˜๋ฆฌ๊ณ  ์‹ถ๋‹ค๋ฉด, ๋‹ค์Œ ์ค‘ ํ•œ๊ฐ€์ง€ ๊ฒฝ์šฐ์ผ ๊ฒ๋‹ˆ๋‹ค.

  1. ๋งจ ์ฒซ ์‚ฌ๋žŒ ์•ž์— ์ถ”๊ฐ€ํ•œ๋‹ค.
  2. ์‚ฌ๋žŒ๊ณผ ์‚ฌ๋žŒ ์‚ฌ์ด์— ์ถ”๊ฐ€ํ•œ๋‹ค.
  3. ๋งจ ๋’ท ์‚ฌ๋žŒ ๋’ค์— ์ถ”๊ฐ€ํ•œ๋‹ค.

1๋ฒˆ์„ ๋จผ์ € ์‚ดํŽด๋ณด๋ฉด, ์ด๋ฏธ ๊ธฐ์ฐจ๋†€์ด๋ฅผ ํ•˜๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ๊ฑฐ๋‚˜ ์—†์„ ์ˆ˜ ์žˆ๊ฒ ๊ตฐ์š”! ๋งˆ์น˜ ์Šˆ๋ขฐ๋”ฉ๊ฑฐ์˜ ๊ณ ์–‘์ด ๊ฐ™์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ปดํ“จํ„ฐ๋Š” ์ด๋Ÿฐ ์œ ๋จธ์— ๋Šฅ์ˆ™ํ•˜์ง€ ๋ชปํ•˜๋ฏ€๋กœ, ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ๋‚˜๋ˆ  ์•Œ๋ ค์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ///๋ฆฌ์ŠคํŠธ์˜ ์ฒ˜์Œ์— ๋…ธ๋“œ ์ถ”๊ฐ€
    @discardableResult
    func insertNodeAtFirst(_ newNode: Node<T>, _ idx: Int)->Node<T>?{
        if self.head == nil{
            self.head = newNode
            return newNode
        }
        newNode.nextNode = self.head
        self.head = newNode
        return newNode
    }

ํ—ค๋“œ๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด ์ƒˆ ๋…ธ๋“œ๋ฅผ ํ—ค๋“œ๋กœ, ํ—ค๋“œ๊ฐ€ ์ด๋ฏธ ์žˆ๋‹ค๋ฉด ํ—ค๋“œ์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ์ƒˆ ๋…ธ๋“œ์˜ ๋‹ค์Œ ๋…ธ๋“œ๋กœ ๋‹ฌ์•„๋†“์€ ํ›„
๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ์ž์ฒด์ ์ธ ํ—ค๋“œ๋Š” ์ƒˆ ๋…ธ๋“œ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๋๋‚ฉ๋‹ˆ๋‹ค.

2๋ฒˆ์„ ์‚ดํŽด๋ณผ๊นŒ์š”. ํƒ€์ž์น˜๊ธฐ ํž˜๋“œ๋‹ˆ ๊ธฐ์ฐจ๋†€์ด ๋น„์œ ๋Š” ์ด์ฏค ๊ทธ๋งŒ๋‘์–ด๋„ ์ดํ•ดํ•˜์‹ค๊ฑฐ๋ผ ์ƒ๊ฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
๋…ธ๋“œ์™€ ๋…ธ๋“œ ์‚ฌ์ด์— ์ƒˆ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ์—, ๋นˆ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋Š” ์ƒˆ ๋…ธ๋“œ๊ฐ€ ํ—ค๋“œ ๋…ธ๋“œ๊ฐ€ ๋˜๊ฒ ๊ตฐ์š”.
์‚ฝ์ž…ํ•˜๋ ค๋Š” ์œ„์น˜๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋‹ค๋ฉด ๋งจ ๋งˆ์ง€๋ง‰์— ๋‹ฌ๊ฑฐ๋‚˜ ๋‹ฌ์ˆ˜ ์—†๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ์— ๋‹ฌ์ง€ ์•Š๊ณ  nil์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด ๋ณผ๊นŒ์š”?

    func insertNodeAt(_ newNode: Node<T>, _ idx: Int)->Node<T>?{
        if self.head == nil{
            self.head = newNode
            return newNode
        }
        var currentNode = head
        for _ in 0..<(idx-1){
            if currentNode == nil {return nil}
            currentNode = currentNode?.nextNode
        }
        newNode.nextNode = currentNode?.nextNode
        currentNode?.nextNode = newNode
        
        return newNode
    }


์ด์ œ ๋ฆฌ์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰์— ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
ํŠน์ • ์œ„์น˜๊นŒ์ง€ ๋„๋‹ฌํ•œ๋‹ค๋Š” ์กฐ๊ฑด์ด ์—†์œผ๋ฏ€๋กœ, for๋ฌธ์„ while๋ฌธ์œผ๋กœ ๋ฐ”๊พผ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ๊ฒ ๋„ค์š”!

    ///๋ฆฌ์ŠคํŠธ ๋งˆ์ง€๋ง‰์— ๋…ธ๋“œ ์ถ”๊ฐ€
    @discardableResult
    func appendNode(_ newNode: Node<T>)->Node<T>{
        if let head = self.head{
            var tail = head
            while(tail.nextNode != nil){
                tail = tail.nextNode!
            }
            tail.nextNode = newNode
        }else{
            self.head = newNode
        }
        return newNode
    }

 

2. ํƒ์ƒ‰

์‚ฌ์‹ค ์‚ฝ์ž…์—์„œ ํ•„์š”๋กœํ•˜๋Š” ๋ชจ๋“  ์†Œ์–‘์„ ์—ฌ๋Ÿฌ๋ถ„๊ป˜์„œ๋Š” ๊ฒฝํ—˜ํ•˜์…จ์Šต๋‹ˆ๋‹ค.
'ํŠน์ • ์œ„์น˜์— ์ ‘๊ทผํ•˜์—ฌ, ์ง€์ •๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค' ๊ฐ€ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์—ฐ์‚ฐ์— ๊ณตํ†ต๋œ ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์ด์ง€์š”.
๊ทธ๋ ‡๋‹ค๋ฉด, ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๊ฐ๊ฐ์˜ ํ•จ์ˆ˜๋ฅผ ์กฐ๊ธˆ ์ˆ˜์ •ํ•˜๋ฉด ๊ธˆ๋ฐฉ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒ ๊ตฐ์š”!

    ///๋ฆฌ์ŠคํŠธ์˜ ํŠน์ • ์œ„์น˜์˜ ๋…ธ๋“œ ๋ฐ˜ํ™˜
    func getNodeAt(_ idx: Int)->Node<T>?{
        if self.head == nil {return nil}
        var currentNode = head
        for _ in 0..<idx{
            if currentNode == nil {return nil}
            currentNode = currentNode?.nextNode
        }
        return currentNode
    }
    ///๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ์œ„์น˜์˜ ๋…ธ๋“œ ๋ฐ˜ํ™˜
    func getNodeAtFirst()->Node<T>?{
        if self.head == nil{return nil}
        return self.head
    }
    ///๋ฆฌ์ŠคํŠธ ๋งˆ์ง€๋ง‰ ์œ„์น˜์˜ ๋…ธ๋“œ ๋ฐ˜ํ™˜
    func getLastNode()->Node<T>?{
        if self.head == nil{return nil}
        var currentNode = self.head
        while(currentNode != nil){
            currentNode = currentNode?.nextNode
        }
        return currentNode
    }

 

3. ์‚ญ์ œ

์‚ญ์ œ ๋˜ํ•œ ์‚ฝ์ž…์˜ ์‘์šฉ์ž…๋‹ˆ๋‹ค. ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ์ง์ „ ๋…ธ๋“œ๊นŒ์ง€ ์ ‘๊ทผํ•˜์—ฌ, nil์„ ํ• ๋‹นํ•˜๋ฉด ๋‚˜๋จธ์ง€๋Š” ๋˜‘๋˜‘ํ•œ ARC๊ฐ€ ์ฒ˜๋ฆฌํ•  ์˜ˆ์ •์ด์ฃ .

    ///๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ๋…ธ๋“œ ์ œ๊ฑฐ
    @discardableResult
    func removeFirst()->Node<T>?{
        if self.head == nil{return nil}
        self.head = self.head?.nextNode
        return head
    }
    ///๋ฆฌ์ŠคํŠธ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ ์ œ๊ฑฐ
    @discardableResult
    func removeLastNode()->Node<T>?{
        if self.head == nil{
            print("List is empty")
            return nil
        }
        
        if self.head?.nextNode == nil {
            var removeNode = self.head
            self.head = nil
            return removeNode
        }
        
        var currentNode = self.head
        while(currentNode?.nextNode?.nextNode != nil){
            if currentNode?.nextNode == nil {break}
            currentNode = currentNode?.nextNode
        }
        var removedNode = currentNode?.nextNode
        currentNode?.nextNode = nil
        return removedNode
        }
    //๋ฆฌ์ŠคํŠธ์˜ ํŠน์ •์œ„์น˜์˜ ๋…ธ๋“œ ์ œ๊ฑฐ
    @discardableResult
    func removeNodeAt(_ idx: Int)->Node<T>?{
        if self.head == nil{
            print("List is empty")
            return nil
        }
        var currentNode = self.head
        for _ in 0..<idx-1{
            if currentNode?.nextNode?.nextNode == nil {break}
            currentNode = currentNode?.nextNode
        }
        let removeNode = currentNode?.nextNode
        currentNode?.nextNode = currentNode?.nextNode?.nextNode
        return removeNode
    }

๋งŒ์•ฝ, ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฆฌ์ŠคํŠธ์˜ ์ธ๋ฑ์Šค์˜ ์œ„์น˜์— ๋…ธ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•˜๋Š”๊ฒƒ์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค๋งŒ...
์ด ๋ถ€๋ถ„์€ ์ทจํ–ฅ๊ป nil์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์‹ค ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”!
์ด์ œ ์ € ํ•จ์ˆ˜๋“ค์„ SingleLinkedList ํด๋ž˜์Šค์— ๋‹ด๋Š”๊ฒƒ์œผ๋กœ ์ฝ”๋”ฉ์€ ๋์ž…๋‹ˆ๋‹ค.

4. ๊ฒฐ๋ก 

์˜ค๋Š˜์€ ๋ฐฐ์—ด๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ๋…€์„, '๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ'์— ๋Œ€ํ•ด ๋„์ ์—ฌ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋Š” ๋ฐฐ์—ด์— ๋น„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ƒˆ๋กœ์šด ๋…ธ๋“œ์˜ ์ถ”๊ฐ€/์‚ฝ์ž…/์‚ญ์ œ๊ฐ€ ์‰ฝ๊ณ  ๋น ๋ฆ…๋‹ˆ๋‹ค.
    ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์— ๋น„ํ•ด ๋ฐฐ์—ด์€ ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ์–ป์–ด์˜ค๋Š” ์—ฐ์‚ฐ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    (๋ผ๊ณ  ์ฑ…์— ์ ํ˜€์žˆ์œผ๋‚˜, ๋งค์šฐ ์ ๋‹ค๊ณ  ๋ฐ›์•„๋“ค์˜€์Šต๋‹ˆ๋‹ค)

์ด์— ๋Œ€๋น„๋˜๋Š” ๋‹จ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํŠน์ • ์œ„์น˜์˜ ๋…ธ๋“œ๋ฅผ ์–ป๋Š”๋ฐ ๋“œ๋Š” ๋น„์šฉ์ด ํฌ๊ณ , ์†๋„๋„ ๋А๋ฆฝ๋‹ˆ๋‹ค.
    ๋ฐฐ์—ด์€ ์ƒ์ˆ˜ ์‹œ๊ฐ„ ( O(1) ) ์— ๋…ธ๋“œ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ฉด, N๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง„ ๋ฆฌ์ŠคํŠธ์˜ ๊ฒฝ์šฐ์— ์ตœ์ž‘์˜ ๊ฒฝ์šฐ NํšŒ์˜ ํƒ์ƒ‰๋ฃจํ”„( O(n) )๋ฅผ ๊ฑฐ์ณ์•ผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋ฅผ ์œ„ํ•˜์—ฌ, 4byte์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋กœ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. (C๊ธฐ์ค€)
    (์–ธ์–ด๋งˆ๋‹ค ๋‹ค๋ฅธ ๋ถ€๋ถ„์ด๊ณ , Swift๋Š” ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด Node<Any>? ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐ์–ด๋ณด์•˜์„ ๋•Œ 8๋ฐ”์ดํŠธ์ž„์„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค)
  • print(MemoryLayout<Node<Any>?>.size) //8

์ด๋กœ์จ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ, ์ •ํ™•ํžˆ '์‹ฑ๊ธ€' ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„์ด ๋งˆ๋ฌด๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๋ช‡๋ช‡ ๋ถ„๋“ค์€ ์—ฌ๋Ÿฌ๋ถ„์€ ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ด SingleLinkedList์ธ ๊ฒƒ๊ณผ, ์‚ฝ์ž… - ์‚ญ์ œ ์‹œ์— ํƒ€๊ฒŸ ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ํƒ€๊ฒŸ ์ง์ „์˜ ๋…ธ๋“œ์— ์ ‘๊ทผํ•˜์—ฌ
์ผ๋ จ์˜ ๋ช…๋ น์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์— ์œ„ํ™”๊ฐ๊ณผ ๋ถˆํŽธํ•จ์„ ๋А๋ผ์…จ์„๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ €๋งŒ ๊ทธ๋Ÿฐ๊ฐ€์š”?
๊ทธ๋‹ค์ง€ ๋†€๋ž์ง€๋Š” ์•Š์ง€๋งŒ, ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋ถˆํŽธํ•จ์„ ๋А๋‚€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. '๋”๋ธ”' ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์„ธ์ƒ์— ํƒ„์ƒํ•œ ๊ฒƒ์„ ๋ณด๋ฉด ๋ง์ด์ฃ !

๋‹ค์Œ ๊ธ€์—์„œ๋Š” ๋”๋ธ” ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•ด ์–˜๊ธฐํ•˜๊ณ , ๊ตฌํ˜„ํ•ด๋ณด๋„๋ก ํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ–๊ฒ ์Šต๋‹ˆ๋‹ค.
์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

(๋‹ค์Œ ๊ธ€ - https://bpeeper.tistory.com/28)

 

[DataStructure] ์ด์ค‘ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋ฅผ Swift๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ

https://m.hanbit.co.kr/store/books/book_view.html?p_code=B3450156021 ์ด ๊ธ€์€ ์ฑ… '๋‡Œ๋ฅผ ์ž๊ทนํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜' ์—์„œ ๋ฐฐ์šด ๋‚ด์šฉ์„ ์ ๊ทน ์ฐธ๊ณ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋ชจ๋“  ์ž๋ฃŒ๊ตฌ์กฐ ๋ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ Swift๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Œ์„

bpeeper.tistory.com

*์†Œ์Šค์ฝ”๋“œ ์ „๋ฌธ

//
//  SingleLinkedList.swift
//  Swift-Practice
//
//  Created by Yune gim on 2024/03/20.
//

class SingleLinkedList<T>{
    var head: Node<T>?
    ///๋ฆฌ์ŠคํŠธ์˜ ํŠน์ • ์œ„์น˜์˜ ๋…ธ๋“œ ๋ฐ˜ํ™˜
    func getNodeAt(_ idx: Int)->Node<T>?{
        if self.head == nil {return nil}
        var currentNode = head
        for _ in 0..<idx{
            if currentNode == nil {return nil}
            currentNode = currentNode?.nextNode
        }
        return currentNode
    }
    ///๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ์œ„์น˜์˜ ๋…ธ๋“œ ๋ฐ˜ํ™˜
    func getNodeAtFirst()->Node<T>?{
        if self.head == nil{return nil}
        return self.head
    }
    ///๋ฆฌ์ŠคํŠธ ๋งˆ์ง€๋ง‰ ์œ„์น˜์˜ ๋…ธ๋“œ ๋ฐ˜ํ™˜
    func getLastNode()->Node<T>?{
        if self.head == nil{return nil}
        var currentNode = self.head
        while(currentNode != nil){
            currentNode = currentNode?.nextNode
        }
        return currentNode
    }
    ///๋ฆฌ์ŠคํŠธ์˜ ์ฒ˜์Œ์— ๋…ธ๋“œ ์ถ”๊ฐ€
    @discardableResult
    func insertNodeAtFirst(_ newNode: Node<T>, _ idx: Int)->Node<T>?{
        if self.head == nil{
            self.head = newNode
            return newNode
        }
        newNode.nextNode = self.head
        self.head = newNode
        return newNode
    }
    ///๋ฆฌ์ŠคํŠธ์˜ ์ค‘๊ฐ„์— ๋…ธ๋“œ ์ถ”๊ฐ€
    @discardableResult
    func insertNodeAt(_ newNode: Node<T>, _ idx: Int)->Node<T>?{
        if self.head == nil{
            self.head = newNode
            return newNode
        }
        var currentNode = head
        for _ in 0..<(idx-1){
            if currentNode == nil {return nil}
            currentNode = currentNode?.nextNode
        }
        newNode.nextNode = currentNode?.nextNode
        currentNode?.nextNode = newNode
        
        return newNode
    }
    ///๋ฆฌ์ŠคํŠธ ๋งˆ์ง€๋ง‰์— ๋…ธ๋“œ ์ถ”๊ฐ€
    @discardableResult
    func appendNode(_ newNode: Node<T>)->Node<T>{
        if let head = self.head{
            var tail = head
            while(tail.nextNode != nil){
                tail = tail.nextNode!
            }
            tail.nextNode = newNode
        }else{
            self.head = newNode
        }
        return newNode
    }
    ///๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ๋…ธ๋“œ ์ œ๊ฑฐ
    @discardableResult
    func removeFirst()->Node<T>?{
        if self.head == nil{return nil}
        self.head = self.head?.nextNode
        return head
    }
    ///๋ฆฌ์ŠคํŠธ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ ์ œ๊ฑฐ
    @discardableResult
    func removeLastNode()->Node<T>?{
        if self.head == nil{
            print("List is empty")
            return nil
        }
        
        if self.head?.nextNode == nil {
            var removeNode = self.head
            self.head = nil
            return removeNode
        }
        
        var currentNode = self.head
        while(currentNode?.nextNode?.nextNode != nil){
            if currentNode?.nextNode == nil {break}
            currentNode = currentNode?.nextNode
        }
        var removedNode = currentNode?.nextNode
        currentNode?.nextNode = nil
        return removedNode
        }
    //๋ฆฌ์ŠคํŠธ์˜ ํŠน์ •์œ„์น˜์˜ ๋…ธ๋“œ ์ œ๊ฑฐ
    @discardableResult
    func removeNodeAt(_ idx: Int)->Node<T>?{
        if self.head == nil{
            print("List is empty")
            return nil
        }
        var currentNode = self.head
        for _ in 0..<idx-1{
            if currentNode?.nextNode?.nextNode == nil {break}
            currentNode = currentNode?.nextNode
        }
        let removeNode = currentNode?.nextNode
        currentNode?.nextNode = currentNode?.nextNode?.nextNode
        return removeNode
    }
    func printAllNode(){
        var currentNode = self.head
        while(currentNode != nil){
            print(currentNode?.data)
            currentNode = currentNode?.nextNode
        }
    }
    
}