๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป Programming ๊ฐœ๋ฐœ/๐ŸŽ iOS ๊ฐœ๋ฐœ, Swift

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ7. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๋„์ „๊ณผ์ œ

by kimdee 2022. 7. 11.
๋ฐ˜์‘ํ˜•

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ7. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ  ๋„์ „๊ณผ์ œ

Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures & Algorithms in Swift ์ฑ…์˜ ๋ฐ๋ชจ ๊ณต๊ฐœ๋ณธ์„ ๋ฒˆ์—ญํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ๊ฒ๊ฒŒ ๋ด์ฃผ์„ธ์š”. 

https://www.raywenderlich.com/books/data-structures-algorithms-in-swift


 

์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ Elementary Data Structure

์ฑ•ํ„ฐ 7. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋„์ „๊ณผ์ œ Linked Lists Challenges

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

 

Start project๋ฅผ ์—ด๋ฉด ์•„๋ž˜ ๋„์ „๊ณผ์ œ๋“ค์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„์ „๊ณผ์ œ 1: ๊ฑฐ๊พธ๋กœ ์ถœ๋ ฅํ•˜๊ธฐ

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋ฅผ ๊ฑฐ๊พธ๋กœ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ด…๋‹ˆ๋‹ค.

 

// ์˜ˆ์ œ 
1 -> 2 -> 3 -> nil

// ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์ถœ๋ ฅ์ด ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
3
2
1

 

๋„์ „๊ณผ์ œ 2: ๊ฐ€์šด๋ฐ ๋…ธ๋“œ ์ฐพ๊ธฐ 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์—์„œ ์ค‘์•™์— ์œ„์น˜ํ•œ ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ด…๋‹ˆ๋‹ค.

 

// ์˜ˆ์ œ

1 -> 2 -> 3 -> 4 -> nil
// ์—ฌ๊ธฐ์„œ ๊ฐ€์šด๋ฐ ๋…ธ๋“œ๋Š” 3์ž…๋‹ˆ๋‹ค.

1 -> 2 -> 3 -> nil
// ์—ฌ๊ธฐ์„œ ๊ฐ€์šด๋ฐ ๋…ธ๋“œ๋Š” 2์ž…๋‹ˆ๋‹ค.

 

๋„์ „๊ณผ์ œ 3: ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๋’ค์ง‘๊ธฐ 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์˜ ์ˆœ์„œ๋ฅผ ๋’ค์ง‘๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ด…๋‹ˆ๋‹ค. ๋…ธ๋“œ๋ฅผ ์ง์ ‘ ๋‹ค๋ฃจ์–ด์„œ ๋ฐ˜๋Œ€๋ฐฉํ–ฅ์œผ๋กœ ์—ฐ๊ฒฐ๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

 

// ์˜ˆ์‹œ 
// ์ „
1 -> 2 -> 3 -> nil

// ํ›„ 
3 -> 2 -> 1 -> nil

 

๋„์ „๊ณผ์ œ 4: ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ 2๊ฐœ ํ•ฉ์น˜๊ธฐ 

๋‘๊ฐœ์˜ ์ •๋ ฌ๋œ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•ฉ์ณ์„œ ํ•˜๋‚˜์˜ ์ •๋ ฌ๋œ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ด…๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ๋‘๊ฐœ์˜ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์— ์žˆ๋Š” ์š”์†Œ๋ฅผ ์ •๋ ฌ๋œ ์ˆœ์„œ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ƒˆ๋กœ์šด ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ •๋ ฌ์ˆœ์„œ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ๊ฐ€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

// ์˜ˆ์‹œ

// ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ 1
1 -> 4 -> 10 -> 11

// ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ 2
-1 -> 2 -> 3 -> 6

// ํ•ฉ์ณ์ง„ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ 
-1 -> 1 -> 2 -> 3 -> 4 -> 6 -> 10 -> 11

 

 

๋„์ „๊ณผ์ œ 5: ํŠน์ • ์š”์†Œ์™€ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ๋Œ€์ƒ์„ ์ œ๊ฑฐ 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์˜ ํŠน์ • ์š”์†Œ์™€ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ด…๋‹ˆ๋‹ค. ์ด์ „์— ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์— ๊ตฌํ˜„ํ•ด๋ณธ remove(at:)  ๋ฉ”์„œ๋“œ์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

 

// ์˜ˆ์‹œ 

// ์›๋ณธ ๋ฆฌ์ŠคํŠธ 
1 -> 3 -> 3 -> 3 -> 4

// ๋ชจ๋“  3์„ ์ œ๊ฑฐํ•œ ๋ฆฌ์ŠคํŠธ 
1 -> 4

ํ•ด๊ฒฐ์ฑ…

๋„์ „ ๊ณผ์ œ 1 ํ•ด๊ฒฐ์ฑ… 

๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์žฌ๊ท€๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์žฌ๊ท€๋ฅผ ์ด์šฉํ•˜๋ฉด ์ฝœ ์Šคํƒ(Call Stack)์„ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฝœ ์Šคํƒ์ด ํ•ด์ œ๋  ๋•Œ ์ถœ๋ ฅ๋ฌธ์„ ํ˜ธ์ถœํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

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

 

private func printInReverse<T>(_ node: Node<T>?) {

  // 1
  guard let node = node else { return }

  // 2
  printInReverse(node.next)
}

 

  1. ๋จผ์ € ์žฌ๊ท€๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ์กฐ๊ฑด์ธ ๊ธฐ๋ณธ ์ผ€์ด์Šค๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ node ๊ฐ€ nil์ด๋ฉด ๋ฆฌ์ŠคํŠธ ๋งˆ์ง€๋ง‰์— ๋„๋‹ฌํ–ˆ๋‹ค๋Š” ๋œป์ด๋ฏ€๋กœ ์ข…๋ฃŒ์กฐ๊ฑด์ด ๋ฉ๋‹ˆ๋‹ค.
  2. ์žฌ๊ท€ํ˜ธ์ถœ์ด๋ฏ€๋กœ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋™์ผํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

์ถœ๋ ฅ

print ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์œ„์น˜์— ๋”ฐ๋ผ ์—ญ์ˆœ์œผ๋กœ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ถœ๋ ฅํ•  ์ง€ ์—ฌ๋ถ€๊ฐ€ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.

 

private func printInReverse<T>(_ node: Node<T>?) {
  guard let node = node else { return }
  printInReverse(node.next)
  print(node.value)
}

 

์žฌ๊ท€ํ˜ธ์ถœ ๋‹ค์Œ์œผ๋กœ ์˜ค๋Š” ์ฝ”๋“œ๋Š” ๊ธฐ๋ณธ ์ผ€์ด์Šค๊ฐ€ ๋ฐœ๋™(์—ฌ๊ธฐ์„œ๋Š” ์žฌ๊ท€ํ˜ธ์ถœ์ด ๋ฆฌ์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰๊นŒ์ง€ ๊ฐ”์„ ๋•Œ)๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์žฌ๊ท€ ๋ฌธ์ด ํ’€๋ฆฌ๊ฒŒ ๋˜๋ฉด์„œ ๋…ธ๋“œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์›๋ž˜์˜ printInReverse ์•ˆ์— ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

func printInReverse<T>(_ list: LinkedList<T>) {
  printInReverse(list.head)
}

 

์‹œ๋„ํ•ด๋ณด๊ธฐ

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ ์•„๋ž˜์— ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

 

example(of: "printing in reverse") {
  var list = LinkedList<Int>()
  list.push(3)
  list.push(2)
  list.push(1)

  print("Original list: \(list)")
  print("Printing in reverse:")
  printInReverse(list)
}

 

์•„๋ž˜ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

---Example of printing in reverse---
Original list: 1 -> 2 -> 3
Printing in reverse:
3
2
1

 

๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ˆœํšŒํ•ด์•ผํ•˜๋ฏ€๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(n) ์ž…๋‹ˆ๋‹ค. ๋ฌต์‹œ์ ์œผ๋กœ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์Šคํƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์š”์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ ๊ณต๊ฐ„๋ณต์žก๋„ ์—ญ์‹œ O(n) ์ž…๋‹ˆ๋‹ค.

 


 

๋„์ „ ๊ณผ์ œ 2 ํ•ด๊ฒฐ์ฑ… 

์ด ํ•ด๊ฒฐ์ฑ…์€ ๋‘ ๊ฐœ์˜ ํฌ์ธํ„ฐ๊ฐ€ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ๋ฅผ ๋ชจ๋‘ ์ˆœํšŒํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘˜ ์ค‘ ํ•œ ํฌ์ธํ„ฐ๋Š” ๋‹ค๋ฅธ ํฌ์ธํ„ฐ๋ณด๋‹ค 2๋ฐฐ ๋น ๋ฅด๊ฒŒ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค. ๋น ๋ฅธ ํฌ์ธํ„ฐ๊ฐ€ ๋ฆฌ์ŠคํŠธ ๋๊นŒ์ง€ ๊ฐ€๊ฒŒ ๋˜๋ฉด ๋Š๋ฆฐ ํฌ์ธํ„ฐ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์ค‘์•™์— ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์—…๋ฐ์ดํŠธํ•˜์„ธ์š”.

 

func getMiddle<T>(_ list: LinkedList<T>) -> Node<T>? {
  var slow = list.head
  var fast = list.head

  while let nextFast = fast?.next {
    fast = nextFast.next
    slow = slow?.next
  }

  return slow
}

 

 while ์„ ์„ ์–ธํ•  ๋•Œ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ nextFast์— ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‹ค์Œ ๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด fast ํฌ์ธํ„ฐ๋ฅผ nextFast ์˜ ๋‹ค์Œ ๋…ธ๋“œ๋กœ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ํšจ๊ณผ์ ์œผ๋กœ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‘๋ฒˆ ์ˆœํšŒํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.  slow ์ฐธ์กฐ๋Š” ํ•œ๋ฒˆ๋งŒ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์„ ๋Ÿฌ๋„ˆ ๊ธฐ๋ฒ• runner’s technique ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

 

์‹œ๋„ํ•ด๋ณด๊ธฐ

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ ์•„๋ž˜์— ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

 

example(of: "getting the middle node") {
  var list = LinkedList<Int>()
  list.push(3)
  list.push(2)
  list.push(1)

  print(list)

  if let middleNode = getMiddle(list) {
    print(middleNode)
  }
}

 

์•„๋ž˜ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

---Example of getting the middle node---
1 -> 2 -> 3
2 -> 3

 

ํ•œ ๋ฒˆ์˜ ํŒจ์Šค๋กœ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜์˜€์œผ๋ฏ€๋กœ ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š”  O(n)  ์ž…๋‹ˆ๋‹ค. ๋Ÿฌ๋„ˆ ๊ธฐ๋ฒ• runner’s technique ์€ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์™€ ์—ฐ๊ด€๋˜์–ด ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

 

 


๋„์ „ ๊ณผ์ œ 3 ํ•ด๊ฒฐ์ฑ… 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘๊ธฐ ์œ„ํ•ด์„œ ๋ชจ๋“  ๋…ธ๋“œ์— ๋ฐฉ๋ฌธํ•˜์—ฌ next ์ฐธ์กฐ๋ฅผ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋…ธ๋“œ์˜ ์ฐธ์กฐ๋“ค์„ ๊ด€๋ฆฌํ•ด์•ผํ•˜๋ฏ€๋กœ ๊นŒ๋‹ค๋กœ์šด ์ž‘์—…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์‰ฌ์šด ๋ฐฉ๋ฒ•

์ƒˆ ๋นˆ ๋ฆฌ์ŠคํŠธ๋กœ push ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ์— ์—…๋ฐ์ดํŠธํ•˜์„ธ์š”.

 

extension LinkedList {

  mutating func reverse() {

    // 1
    let tmpList = LinkedList<Value>()
    for value in self {
      tmpList.push(value)
    }

    // 2
    head = tmpList.head
  }
}

 

  1. ๋จผ์ € ํ˜„์žฌ ๊ฐ’์„ ๋ชจ๋‘ ์ƒˆ tmpList ๋ฆฌ์ŠคํŠธ์— ํ‘ธ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—ญ์ˆœ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  2. head ์ฐธ์กฐ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค.

O(n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„์ธ๋ฐ๋‹ค ์‰ฝ๊ณ  ๊ฐ„ํŽธํ•˜์ง€์š”.

 

ํ•˜์ง€๋งŒ ์ž ๊น...

๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘๋Š” ๋ฐ์— O(n) ์€ ์ตœ์ ์˜ ์‹œ๊ฐ„๋ณต์žก๋„์ง€๋งŒ, ์ด์ „ ๋ฐฉ์‹์€ ์ƒ๋‹นํ•œ ๋ฆฌ์†Œ์Šค ๋น„์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. reverse ๋Š” ์ƒˆ ๋ฆฌ์ŠคํŠธ์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ๊ฐ๊ฐ push ๋ฉ”์„œ๋“œ๋กœ ํ• ๋‹นํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ๊ฐ ๋…ธ๋“œ์˜ next ํฌ์ธํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ์ข€ ๋” ๋ณต์žกํ•ด์ง€๊ฒ ์ง€๋งŒ ์„ฑ๋Šฅ ๋ฉด์—์„œ ์ƒ๋‹นํ•œ ์ด์ ์„ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

reverse() ๋ฉ”์„œ๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

 

mutating func reverse() {
  tail = head
  var prev = head
  var current = head?.next
  prev?.next = nil

  // ...
}

 

๋จผ์ € head ๋ฅผ tail ์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ๋‘๊ฐœ์˜ ์ฐธ์กฐ prev ์™€ current ๋ฅผ ๋งŒ๋“ค์–ด ์ˆœํšŒ๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ „๋žต์€ ๊ฝค ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค. ๊ฐ ๋…ธ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์—์„œ ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ๋ฅผ ํƒ์ƒ‰ํ•˜๋ฉด์„œ ๊ฐ ๋…ธ๋“œ๊ฐ€ ์ด์ „ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ๋ณด์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ด ๊ณผ์ •์€ ๊ฝค ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. current ๋ฅผ prev ๋กœ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋˜๋ฉด ๋ฆฌ์ŠคํŠธ์˜ ๋‚˜๋จธ์ง€์— ๋Œ€ํ•œ ๋งํฌ๋ฅผ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— ์„ธ๋ฒˆ์งธ ํฌ์ธํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. reverse ๋ฉ”์„œ๋“œ ์•„๋ž˜์— ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

 

while current != nil {
  let next = current?.next
  current?.next = prev
  prev = current
  current = next
}

 

๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘์„ ๋•Œ๋งˆ๋‹ค, ๋‹ค์Œ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ณผ์ •์ด ๋๋‚˜๋ฉด ๋‘๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ๋‹ค์Œ ๋‘๊ฐœ์˜ ๋…ธ๋“œ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ์ฐธ์กฐ๋ฅผ ๋’ค์ง‘์—ˆ๋‹ค๋ฉด, head ๋ฅผ ๋ฆฌ์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. reverse ๋ฉ”์„œ๋“œ ๋งจ ๋์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

 

head = prev

 

์‹œ๋„ํ•ด๋ณด๊ธฐ

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ ์•„๋ž˜์— ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

 

example(of: "reversing a list") {
  var list = LinkedList<Int>()
  list.push(3)
  list.push(2)
  list.push(1)

  print("Original list: \(list)")
  list.reverse()
  print("Reversed list: \(list)")
}

 

์•„๋ž˜ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

---Example of reversing a list---
Original list: 1 -> 2 -> 3
Reversed list: 3 -> 2 -> 1

 

์ด reverse ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” ์—ฌ์ „ํžˆ O(n) ์ž…๋‹ˆ๋‹ค. ์ด์ „์— ๋‹ค๋ฃจ์—ˆ๋˜ ์‰ฌ์šด ๊ตฌํ˜„๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ž„์‹œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด Node ์˜ค๋ธŒ์ ํŠธ๋ฅผ ํ• ๋‹นํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์„ฑ๋Šฅ์„ ์ƒ๋‹นํžˆ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


๋„์ „ ๊ณผ์ œ 4 ํ•ด๊ฒฐ์ฑ… 

์ด ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ์ฑ…์€ ๋‘๊ฐœ์˜ ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ์—์„œ ๋…ธ๋“œ๋ฅผ ๊ณ„์†ํ•ด์„œ ๋ฝ‘์•„์„œ ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ •๋ ฌ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋‘ ๋ฆฌ์ŠคํŠธ์˜ next๋…ธ๋“œ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ƒˆ ๋ฆฌ์ŠคํŠธ์— ๋‹ค์Œ์œผ๋กœ ์ถ”๊ฐ€๋  ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์„ค์ •ํ•˜๊ธฐ

๋‘ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ  mergeSorted์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

guard !left.isEmpty else {
  return right
}

guard !right.isEmpty else {
  return left
}

var newHead: Node<T>?

๋งŒ์•ฝ ํ•˜๋‚˜๊ฐ€ ๋น„์—ˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ํ•˜๋‚˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. Node ์˜ค๋ธŒ์ ํŠธ์˜ ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ง€๋„๋ก ํ•˜๋Š” ์ƒˆ ์ฐธ์กฐ๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. ์ด ์ „๋žต์€ left ์™€ right ์˜ ๋…ธ๋“œ๋“ค์„ newHead ์— ์ •๋ ฌ๋œ ์ˆœ์„œ๋กœ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ newHead ์•„๋ž˜์— ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

// 1
var tail: Node<T>?
var currentLeft = left.head
var currentRight = right.head
// 2
if let leftNode = currentLeft, let rightNode = currentRight {
  if leftNode.value < rightNode.value {
    newHead = leftNode
    currentLeft = leftNode.next
  } else {
    newHead = rightNode
    currentRight = rightNode.next
  }
  tail = newHead
}

 

  1. ์ถ”๊ฐ€ํ•˜๋ ค๋Š” ์ƒˆ ๋ชฉ๋ก์˜ tail ํฌ์ธํ„ฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. 
  2. newHead ์— ํ• ๋‹นํ•˜๊ธฐ ์œ„ํ•ด left ์™€ right ์˜ ์ฒซ๋ฒˆ์งธ ๋…ธ๋“œ๋“ค์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

 

๋ณ‘ํ•ฉํ•˜๊ธฐ

๋‹ค์Œ์œผ๋กœ ์ƒˆ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ •๋ ฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ํ•  ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•˜์—ฌ left ์™€ right ๋ชจ๋‘๋ฅผ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๋์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

// 1
while let leftNode = currentLeft, let rightNode = currentRight {
  // 2
  if leftNode.value < rightNode.value {
    tail?.next = leftNode
    currentLeft = leftNode.next
  } else {
    tail?.next = rightNode
    currentRight = rightNode.next
  }
  tail = tail?.next
}

 

  1. while ๋ฐ˜๋ณต๋ฌธ์€ ๋ฆฌ์ŠคํŠธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค.
  2. ์ด์ „๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋…ธ๋“œ๋“ค์„ ๋น„๊ตํ•˜์—ฌ tail ์— ์—ฐ๊ฒฐํ•  ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

 

์ด ๋ฐ˜๋ณต๋ฌธ์€ currentLeft ์™€ currentRight ์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์ŠคํŠธ ์ค‘์— ๋…ธ๋“œ๊ฐ€ ๋‚จ์•„์žˆ์–ด๋„ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚จ์€ ๋…ธ๋“œ๋“ค์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

 

if let leftNodes = currentLeft {
  tail?.next = leftNodes
}

if let rightNodes = currentRight {
  tail?.next = rightNodes
}

 

๋‚จ์€ ๋…ธ๋“œ๋“ค์„ ๋ถ™์ด๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

 

๋งˆ๋ฌด๋ฆฌ ํ•˜๊ธฐ ์œ„ํ•ด์„œ, ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์— append ๋‚˜ insert ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๋Œ€์‹  ๋ฆฌ์ŠคํŠธ์˜ head ์™€ tail ์˜ ์ฐธ์กฐ๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

var list = LinkedList<T>()
list.head = newHead
list.tail = {
  while let next = tail?.next {
    tail = next
  }
  return tail
}()
return list

 

์‹œ๋„ํ•ด๋ณด๊ธฐ

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ ์•„๋ž˜์— ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

 

example(of: "merging two lists") {
  var list = LinkedList<Int>()
  list.push(3)
  list.push(2)
  list.push(1)
  var anotherList = LinkedList<Int>()
  anotherList.push(-1)
  anotherList.push(-2)
  anotherList.push(-3)
  print("First list: \(list)")
  print("Second list: \(anotherList)")
  let mergedList = mergeSorted(list, anotherList)
  print("Merged list: \(mergedList)")
}

 

์•„๋ž˜ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

---Example of merging two lists---
First list: 1 -> 2 -> 3
Second list: -3 -> -2 -> -1
Merged list: -3 -> -2 -> -1 -> 1 -> 2 -> 3

 

์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€  O(m + n)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. m ์€ ์ฒซ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ์˜ ๋…ธ๋“œ ๊ฐœ์ˆ˜์ด๊ณ  n ์€ ๋‘๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ์˜ ๋“œ ๊ฐœ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

 


 

๋„์ „ ๊ณผ์ œ 5 ํ•ด๊ฒฐ์ฑ… 

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

 

๋ช‡ ๊ฐ€์ง€ ๊ณ ๋ คํ•  ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ๋ฒˆ์งธ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์•ž๋ถ€๋ถ„์—์„œ ๋…ธ๋“œ๋ฅผ ์ง€์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํ—ค๋“œ๋ฅผ ์ž˜๋ผ๋‚ด๊ธฐ

 

์ฒซ๋ฒˆ์งธ๋กœ ๊ณ ๋ คํ•  ์ผ€์ด์Šค๋Š” ๋ฆฌ์ŠคํŠธ์˜ ํ—ค๋“œ๊ฐ€ ์—ฌ๋Ÿฌ๋ถ„์ด ์ œ๊ฑฐํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๋•Œ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜ ๋ฆฌ์ŠคํŠธ์—์„œ 1์„ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…๋‹ˆ๋‹ค.

 

ํ—ค๋“œ → 1 → 1 → 2

 

๊ทธ๋ ‡๋‹ค๋ฉด ์—ฌ๋Ÿฌ๋ถ„์€ ์ƒˆ๋กœ์šด ํ—ค๋“œ๊ฐ€ 2๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ  remove ํ•จ์ˆ˜์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

 

 

while let head = head, head.value == value {
  head = head?.next
}

 

๋จผ์ € ๋ฆฌ์ŠคํŠธ์˜ ํ—ค๋“œ์— ์ œ๊ฑฐํ•˜๋Š” ๊ฐ’์ด ์žˆ์„ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ€์ง„ ์ผ๋ จ์˜ ๋…ธ๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ while ๋ฐ˜๋ณต๋ฌธ์„ ์ด์šฉํ•˜์—ฌ ๋ชจ๋‘ ์ œ๊ฑฐํ•˜์˜€๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

 

 

๋…ธ๋“œ์˜ ์—ฐ๊ฒฐ์„ ๋Š์–ด๋‚ด๊ธฐ

 

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์™€ ๊ด€๋ จ๋œ ๋‹ค๋ฅธ ๋งŽ์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ฒ˜๋Ÿผ ํฌ์ธํ„ฐ ์‚ฐ์ˆ  ์—ฐ์‚ฐ์„ ์ด์šฉํ•˜์—ฌ ๋…ธ๋“œ๋ฅผ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ  remove์˜ ์•„๋ž˜์ชฝ์— ์ถ”๊ฐ€ํ•˜์„ธ์š”.

 

var prev = head
var current = head?.next
while let currentNode = current {
  guard currentNode.value != value else {
    prev?.next = currentNode.next
    current = prev?.next
    continue
  }
  // more to come
}

 

 

๋‘๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•ด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. guard ๋ฌธ์˜ else ๋ธ”๋Ÿญ์€ ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ๋™์ž‘๋ฉ๋‹ˆ๋‹ค.

์›ํ•˜์ง€ ์•Š๋Š” ๋…ธ๋“œ๋ฅผ ์šฐํšŒํ•˜๋„๋ก ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

 

๊ณ„์† ์ž‘์—…ํ•˜๊ธฐ

๋ญ˜ ๊นœ๋ฐ•ํ–ˆ์„๊นŒ์š”? ์œ„์˜ ๊ฒฝ์šฐ while ๋ฌธ์€ ์ ˆ๋Œ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. prev ์™€ current ํฌ์ธํ„ฐ๋ฅผ ํ•จ๊ป˜ ์ด๋™ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. while ๋ฐ˜๋ณต๋ฌธ ํ•˜๋‹จ guard ๋ฌธ ๋’ค์ชฝ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

 

prev = current
current = current?.next

 

 

๋งˆ์ง€๋ง‰์œผ๋กœ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ์˜ tail ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์›๋ž˜์˜ tail ์ด ์ œ๊ฑฐํ•˜๋ ค๋Š” ๊ฐ’์ด ์žˆ๋Š” ๋…ธ๋“œ์ผ ๊ฒฝ์šฐ ํ•„์š”ํ•œ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์„ removeAll ๋์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

 

tail = prev

 

 

์‹œ๋„ํ•ด๋ณด๊ธฐ

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ ์•„๋ž˜์— ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

 

example(of: "deleting duplicate nodes") {
  var list = LinkedList<Int>()
  list.push(3)
  list.push(2)
  list.push(2)
  list.push(1)
  list.push(1)

  list.removeAll(3)
  print(list)
}

์•„๋ž˜ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

---Example of deleting duplicate nodes---
1 -> 1 -> 2 -> 2

์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ง€๋‚˜๊ฐ€์•ผ ํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(n) ์ž…๋‹ˆ๋‹ค.

 

 

๐Ÿ”— ๋ฒˆ์—ญ ์‹œ๋ฆฌ์ฆˆ ๋งํฌ

0๏ธโƒฃ ์„น์…˜ 0. ์‹œ์ž‘ํ•˜๊ธฐ์ „์—

 

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 0. ์‹œ์ž‘ํ•˜๊ธฐ ์ „์—

์š”์ฆ˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ณต๋ถ€๋ฅผ ํ•˜๋ฉด์„œ Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures & Algorithms in Swift์ด ์ฑ…์„ ๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. https://www.raywenderlich.com/books/data-structures-algorithms-in-swift ์ €๋Š” ์ •..

kimdee.tistory.com

1๏ธโƒฃ ์„น์…˜ 1. ์†Œ๊ฐœ Introduction

> ์ฑ•ํ„ฐ 1.์™œ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฐฐ์›Œ์•ผํ• ๊นŒ์š”? / ์ฑ•ํ„ฐ 2. ๋ณต์žก๋„  Complexity

 

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 1. ์†Œ๊ฐœ - ์ฑ•ํ„ฐ1. ์™œ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„

Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures & Algorithms in Swift ์ฑ…์˜ ๋ฐ๋ชจ ๊ณต๊ฐœ๋ณธ์„ ๋ฒˆ์—ญํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ๊ฒ๊ฒŒ ๋ด์ฃผ์„ธ์š”. https://www.raywenderlich.com/books/data-structures-algorithms-in-swift ์„น์…˜..

kimdee.tistory.com

> ์ฑ•ํ„ฐ3. ์Šค์œ„ํ”„ํŠธ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Swift Standard Library

 

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 1. ์†Œ๊ฐœ - ์ฑ•ํ„ฐ3. ์Šค์œ„ํ”„ํŠธ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ S

Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures & Algorithms in Swift ์ฑ…์˜ ๋ฐ๋ชจ ๊ณต๊ฐœ๋ณธ์„ ๋ฒˆ์—ญํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ๊ฒ๊ฒŒ ๋ด์ฃผ์„ธ์š”. https://www.raywenderlich.com/books/data-structures-algorithms-in-swift ์„น์…˜..

kimdee.tistory.com

 

1๏ธโƒฃ ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ Elementary Data Structure

> ์ฑ•ํ„ฐ 4. ์Šคํƒ Stacks /  ์ฑ•ํ„ฐ 5. ์Šคํƒ ๋„์ „๊ณผ์ œ Stack Challenges

 

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ4~5. ์Šคํƒ, ์Šคํƒ ๋„์ „

Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures & Algorithms in Swift ์ฑ…์˜ ๋ฐ๋ชจ ๊ณต๊ฐœ๋ณธ์„ ๋ฒˆ์—ญํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ๊ฒ๊ฒŒ ๋ด์ฃผ์„ธ์š”. https://www.raywenderlich.com/books/data-structures-algorithms-in-swift ์„น์…˜..

kimdee.tistory.com

> ์ฑ•ํ„ฐ 6-1. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ Linked List (์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ์ •์˜, ์š”์†Œ ์ถ”๊ฐ€, ์‚ญ์ œ)

 

 

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ6-1. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ (์ •

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ6-1. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures & Algorithms in Swift ์ฑ…์˜ ๋ฐ๋ชจ ๊ณต๊ฐœ๋ณธ์„ ๋ฒˆ์—ญํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ๊ฒ..

kimdee.tistory.com

> ์ฑ•ํ„ฐ 6-2. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ Linked List (์Šค์œ„ํ”„ํŠธ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ฝœ๋ ‰์…˜ ํ”„๋กœํ† ์ฝœ, ์นด์šฐ Copy-On-Write,  ๋ฐธ๋ฅ˜ ์‹œ๋งจํ‹ฑ)

 

 

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ6-2. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ6-2. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ (์Šค์œ„ํ”„ํŠธ ์ฝœ๋ ‰์…˜ ํ”„๋กœํ† ์ฝœ, ๋ฐธ๋ฅ˜ ์‹œ๋งจํ‹ฑ, COW(์นดํ”ผ-์˜จ-๋ผ์ดํŠธ)) Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures &..

kimdee.tistory.com

 

> ์ฑ•ํ„ฐ 7. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๋„์ „๊ณผ์ œ Linked List Challenges

 

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ7. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๋„์ „

[Swift][๋ฒˆ์—ญ] ์Šค์œ„ํ”„ํŠธ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์„น์…˜ 2. ๊ธฐ์ดˆ ์ž๋ฃŒ๊ตฌ์กฐ - ์ฑ•ํ„ฐ7. ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๋„์ „๊ณผ์ œ Raywenderlich.com ์—์„œ ๋‚˜์˜จ Data Structures & Algorithms in Swift ์ฑ…์˜ ๋ฐ๋ชจ ๊ณต๊ฐœ๋ณธ์„ ๋ฒˆ์—ญํ•˜์˜€์Šต๋‹ˆ๋‹ค..

kimdee.tistory.com

 

 


๋งˆ์น˜๋ฉฐ 

 

์˜ค๋Š˜๋„ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

 

๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ, ๋„์›€์ด ๋˜์…จ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

ํ˜น์‹œ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ํ”ผ๋“œ๋ฐฑํ•˜์‹ค  ๋‚ด์šฉ ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“  ๋Œ“๊ธ€๋กœ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

 

 

 

 

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€