ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

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

๋…ธ๋“œ์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ์†์„ฑ(value)์™€ ๋‹ค์Œ ๋…ธ๋“œ์˜ ์ฃผ์†Œ(pointer)๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฌด์Šจ ๋ง์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค๋ฉด..

 

์ด ๊ธ€์˜ ์ œ๋ชฉ์ฒ˜๋Ÿผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ์ง€ํ•˜์ฒ .์„ ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ์Šต๋‹ˆ๋‹ค!

(์„ค๊ตญ ์—ด์ฐจ๋Š” ๋’ค์—์„œ ์„ค๋ช…๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.๐Ÿ˜Ž)

 

 

์ง€ํ•˜์ฒ ์€ ์—ฌ๋Ÿฌ ๊ฐ์‹ค๋“ค์ด ์—ฐ๊ฒฐ๋œ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.

๊ฐ์‹ค์—๋Š” ์Šน๊ฐ(๋ฐ์ดํ„ฐ)๊ฐ€ ํƒ€๊ณ  ์žˆ๊ณ , ๊ฐ ๊ฐ์‹ค๋“ค์„ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์—ฐ๊ฒฐ์„ (์—ฃ์ง€, ๋งํฌ)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ์ถœ์ฒ˜: https://blog.hyundai-rotem.co.kr/515

 

๋‹ค์‹œ ํ•œ๋ฒˆ, ์ง€ํ•˜์ฒ ์„ ๋จธ๋ฆฌ ์†์— ๋– ์˜ฌ๋ฆฌ๋ฉฐ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ์ •์˜์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด๋ณด์‹œ์ฃ .

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

 

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ๋Š” ๊ฐ์‹ค์„ ๋…ธ๋“œ(node)๋ผ๊ณ  ๋ถ€๋ฅด๊ณ , ๊ฐ์‹ค์„ ์—ฐ๊ฒฐํ•˜๋Š” ์—ฐ๊ฒฐ์„ ์„ ์—ฃ์ง€(edge)๋˜๋Š” ๋งํฌ(link)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค๋Š” ๊ฒƒ ๋นผ๊ณ ๋Š” ๋น„์Šทํ•œ ํ˜•ํƒœ์˜ ๊ตฌ์กฐ๋ฅผ ๋„๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์ด์ œ ์กฐ๊ธˆ์€ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋จธ๋ฆฌ ์†์—์„œ ์—ฐ์ƒ์ด ๋˜์‹œ๋‚˜์š” ?! ๐Ÿค“


Singly Liked List๋Š” ์„ค๊ตญ ์—ด์ฐจ, Doubly Liked List๋Š” ์ง€ํ•˜์ฒ .

๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ '์„ค๊ตญ์—ด์ฐจ'๋ผ๋Š” ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List), ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Doubly Linked List), 

์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Circular Linked List)์™€ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List): ๊ฐ ๋…ธ๋“œ์˜ ๋งํฌ๊ฐ€ ๋‹ค์Œ ๋…ธ๋“œ๋งŒ์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
  • ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Doubly Linked List): ๊ฐ ๋…ธ๋“œ์˜ ๋งํฌ๊ฐ€ ์•ž์˜ ๋…ธ๋“œ์™€ ๋’ค์˜ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
  • ์›ํ˜• ๋ฆฌ์ŠคํŠธ(Circularly Liked List): ์ฒ˜์Œ ๋…ธ๋“œ์™€ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ์„ ํ˜• ๊ตฌ์กฐ๊ฐ€ ์•„๋‹Œ ์›ํ˜• ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์„ค๊ตญ์—ด์ฐจ๋Š” ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์™€ ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•œ ๋น„์œ ๋กœ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

(+ ์˜ํ™” '์„ค๊ตญ์—ด์ฐจ'๋ฅผ ๋ชจ๋ฅด์‹œ๋Š” ๋ถ„๋“ค์„ ์œ„ํ•ด ๊ฐ„๋žตํžˆ ์„ค๋ช…๋“œ๋ฆฌ์ž๋ฉด, ์„ค๊ตญ์—ด์ฐจ๋Š” ์—ฌ๋Ÿฌ ๊ฐ์‹ค๋กœ ์ด๋ฃจ์–ด์ง„ ๊ธฐ์ฐจ๋กœ, 

๊ฐ ๊ฐ์‹ค์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ„๊ธ‰์ด ์กด์žฌํ•˜๋ฉฐ ๊ผฌ๋ฆฌ ์นธ์— ์žˆ๋Š” ์ตœํ•˜์œ„ ๊ณ„์ธต์€ ์ƒ๋ถ€ ์นธ์œผ๋กœ ๊ฐˆ ์ˆ˜ ์—†๋Š” ์—ด์ฐจ์ž…๋‹ˆ๋‹ค.)

 

 

์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋– ์˜ฌ๋ฆด ๋•Œ๋Š” ์ง€ํ•˜์ฒ ์„ ์—ฐ์ƒํ•˜๋ฉด ๋˜๊ณ , ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ์„ค๊ตญ์—ด์ฐจ๋ฅผ ์—ฐ์ƒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

์„ค๊ตญ์—ด์ฐจ๋Š” ๋†’์€ ๊ณ„์ธต๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” ๋จธ๋ฆฌ ์นธ์—์„œ๋Š” ํ•˜์œ„ ๊ณ„์ธต์ด ์‚ฌ๋Š” ๊ผฌ๋ฆฌ ์นธ์œผ๋กœ ๊ฐˆ ์ˆ˜ ์žˆ์ง€๋งŒ, 

๊ผฌ๋ฆฌ ์นธ์—์„œ๋Š” ๋จธ๋ฆฌ ์นธ์œผ๋กœ ๊ฐˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋„ ํ—ค๋“œ ๋…ธ๋“œ์—์„œ ํ…Œ์ผ ๋…ธ๋“œ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ๊ฐˆ ์ˆ˜ ์žˆ๊ณ  ๊ทธ ๋ฐ˜๋Œ€๋Š” ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

(์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ๋…ธ๋“œ๋ฅผ ํ—ค๋“œ(Head)๋…ธ๋“œ, ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ํ…Œ์ผ(Tail)๋…ธ๋“œ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.)

 

 

๊ทธ๋Ÿฌ๋‚˜ ๋ฐ˜๋Œ€๋กœ ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ง€ํ•˜์ฒ ๋กœ ๋น„์œ ํ•œ ์ด์œ ๋Š”, 

์ง€ํ•˜์ฒ ์„ ์ด์šฉํ•œ ๊ฒฝํ—˜์ด ์žˆ๋Š” ๋ถ„์ด๋ผ๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ํ•ด๋‹น ์นธ์—์„œ๋Š” ์•ž์œผ๋กœ๋„ ๊ฐˆ ์ˆ˜ ์žˆ๊ณ  ๋’ค๋กœ๋„ ๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ํ•ด๋‹น ๋…ธ๋“œ์˜ ์•ž ๋…ธ๋“œ์™€ ๋’ค ๋…ธ๋“œ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Array์™€ Liked List ์ฐจ์ด

์ด์ฏค ๋˜์–ด์„œ ํ•œ ๊ฐ€์ง€ ๊ถ๊ธˆ์ฆ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์•„๋‹ˆ๋ฉด ๊ทธ๋งŒ...๐Ÿ˜…)

 

๋ฐฐ์—ด(Array)๊ณผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Linked List)์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? ๐Ÿง

 

์ด์ „์— ์ž๋ฃŒ๊ตฌ์กฐ์— ๊ด€ํ•œ ํฌ์ŠคํŒ…์—์„œ ๋‹ค๋ค˜๋˜ ๋‚ด์šฉ์„ ๋‹ค์‹œ ์‚ดํŽด๋ณด๋ฉด, 

์Šคํƒ(Stack)๊ณผ ํ(Queue)๋Š” ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. 

 

๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์—ฐ์†์ ์œผ๋กœ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์—, 

์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด O(1) ์‹œ๊ฐ„์— ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๊ทธ๋Ÿฌ๋‚˜ ๋ฐฐ์—ด์—์„œ ๋งจ ์•ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ

ํ•ด๋‹น ์ธ๋ฑ์Šค์˜ ๋ฐ์ดํ„ฐ ๊ณต๊ฐ„์ด ๋น„๊ฒŒ ๋˜๋ฏ€๋กœ ๋’ค์— ์œ„์น˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ํ•œ ์นธ์”ฉ ์•ž์œผ๋กœ ์ด๋™์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์˜ค๋ฒ„ ํ—ค๋“œ)

์ด๋กœ ์ธํ•ด O(n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

(๊ทธ๋ž˜์„œ ๋ฐฐ์—ด์„ ์ด์šฉํ•˜์—ฌ ํ(Queue)๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์‹ค์ œ๋กœ ๋ฐฐ์—ด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ,

์ฒซ ๋ฐ์ดํ„ฐ์˜ ์ธ๋ฑ์Šค๋ฅผ ๊ณ„์†ํ•ด์„œ ์กฐ์ ˆํ•˜์—ฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ํ”ผํ–ˆ์Šต๋‹ˆ๋‹ค. ์ดํ•ด๊ฐ€ ์–ด๋ ต๋‹ค๋ฉด ์ฐธ๊ณ  ํ•ด์ฃผ์„ธ์š”.)

 

 

๋ฐ˜๋ฉด, ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋‹ค์Œ ๋…ธ๋“œ์˜ ์ฃผ์†Œ(๋งํฌ, ์—ฃ์ง€)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์ด ๊ตฌ์กฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ๋ฐ์ดํ„ฐ(Node)๊ฐ€ ํฉ์–ด์ ธ ์žˆ๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. 
๋”ฐ๋ผ์„œ ๋ฐฐ์—ด๊ณผ ๋‹ฌ๋ฆฌ ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ๋…ธ๋“œ์— ์ €์žฅ๋œ ๋‹ค๋ฅธ ๋…ธ๋“œ์˜ ์ฃผ์†Œ๋ฅผ ๋”ฐ๋ผ๊ฐ€์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

 

๋”ฐ๋ผ์„œ ๋งจ ์•ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•ด๋„ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„ O(1)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. 

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

 

์š”์•ฝํ•˜์ž๋ฉด, 

๋ฐฐ์—ด์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์—ฐ์†์ ์œผ๋กœ ์ €์žฅ๋˜์–ด ์žˆ์–ด ์ธ๋ฑ์Šค๋ฅผ ํ†ตํ•œ ๋น ๋ฅธ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, 

์‚ญ์ œ ์‹œ์—๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋ฐ˜๋ฉด์— ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ํฉ์–ด์ ธ ์žˆ์–ด ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•˜๋ฉฐ, 

์‚ญ์ œ ์‹œ์—๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ–๋Š” ๋…ธ๋“œ๋งŒ ์ œ๊ฑฐํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ์— ๊ด€๋ จํ•˜์—ฌ ๋” ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜ ๊ธ€์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.๐Ÿ“

<Linked List>


Singly Liked List์™€ Doubly Liked List ์ฐจ์ด

๋„ˆ๋ฌด ๊ธธ์–ด์งˆ๊นŒ๋ด ์ƒ๋žตํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์ €์˜ ๋งŒ์กฑ๋„๋ฅผ ๋†’์ด๊ณ  ์‹ถ์–ด ์ถ”๊ฐ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.๐Ÿ˜… 

 

์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์™€ ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ์ฐจ์ด๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค.

 

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

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ณด๋‹ค ๋” ๋น ๋ฅธ ์‹œ๊ฐ„์— ํƒ์ƒ‰์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์˜ˆ๋ฅผ ๋“ค์–ด 100๊ฐœ์˜ ๋…ธ๋“œ๊ฐ€ ์ €์žฅ๋œ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์ธ๋ฐ 

๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ฒฝ์šฐ 99๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ถ€ํ„ฐ 99๋ฒˆ์˜ ํƒ์ƒ‰์„ ํ•ด์•ผํ•˜์ง€๋งŒ, 

์–‘๋ฐฉํ–ฅ์˜ ๊ฒฝ์šฐ๋Š” ๋’ค์—์„œ๋ถ€ํ„ฐ์ธ 100๋ฒˆ์งธ ๋…ธ๋“œ๋ถ€ํ„ฐ ํƒ์ƒ‰์„ ํ•˜์—ฌ ๋‹จ 2๋ฒˆ๋งŒ์— 99๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์œ„์˜ ์˜ˆ์‹œ๋งŒ ๋ณด๋ฉด ๋ฌด์กฐ๊ฑด ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋” ์ข‹์•„๋ณด์ด์ง€๋งŒ, ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ๋…ธ๋“œ๊ฐ€ ์•ž์˜ ๋…ธ๋“œ์˜ ๋งํฌ๋งŒ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ด์ „ ๋…ธ๋“œ์˜ ๋งํฌ๋„ ์ €์žฅํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—,

๊ทธ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋ชจ๊ฐ€ ๋” ํฌ๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฐ„ ๋ณต์žก๋„๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

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


Swift๋กœ Doubly Liked List ๊ตฌํ˜„

์ด์ œ ์ง์ ‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์›ํ˜•์œผ๋กœ ์—ฐ๊ฒฐ๋œ ์›ํ˜• ๋ฆฌ์ŠคํŠธ๋กœ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ด๋•Œ, ๊ธฐ์ค€ ๋…ธ๋“œ ์—ญํ• ์„ ํ•˜๋Š” dummy ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์„œ๋“œ๋“ค์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

(dummy node์˜ dat๋Š” nil๋กœ ์ง€์ •ํ•˜๊ณ , dummy node๊ฐ€ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ head ๋…ธ๋“œ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.)

 

์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ตํžŒ๋‹ค๋ฉด, ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ๋น„๊ต์  ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

(๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ๋Š” ํ—ค๋“œ ๋…ธ๋“œ๋ฅผ ๋”๋ฏธ๋กœ ์‚ฌ์šฉํ•  ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค!)

 

Node ์ƒ์„ฑ  

// Doubly Linked List Node
class DoublyLinkedListNode<T: Equatable>: Equatable {
    static func == (lhs: DoublyLinkedListNode<T>, rhs: DoublyLinkedListNode<T>) -> Bool {
        return lhs === rhs
    }
    
    let data: T?
    var next: DoublyLinkedListNode?
    weak var previous: DoublyLinkedListNode?
    
    init(data: T?) {
        self.data = data
        self.next = self
        self.previous = self
    }
}

 

(๋‚˜์ค‘์— ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด ์ œ๋„ค๋ฆญ์œผ๋กœ ์„ ์–ธํ•ด์ฃผ์—ˆ์ง€๋งŒ, ์ฝ”ํ…Œ ๋ฌธ์ œ์— ๋”ฐ๋ผ ์•ฝ๊ฐ„์”ฉ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒƒ๋“ค์ด ์žˆ์–ด์„œ ์–ด๋–ค ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š”์ง€๋งŒ ๋ณด๋ฉด ๋  ๊ฑฐ ๊ฐ™์•„์š”!)

 

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

next์™€ previous ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ์–ธํ•ด์ค๋‹ˆ๋‹ค.

 

์ œ๋„ค๋ฆญ์œผ๋กœ ์„ ์–ธํ•ด์คฌ๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜์ค‘์— ๋น„๊ต๋ฅผ ์œ„ํ•ด Equatable ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•ด์ค๋‹ˆ๋‹ค.

๋น„๊ต๋Š” ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ™์€์ง€๋ฅผ ํ™•์ธํ•ด์ฃผ๊ธฐ ์œ„ํ•ด '===' ๋ฅผ ์‚ฌ์šฉํ•ด์ค๋‹ˆ๋‹ค.

<์ฐธ๊ณ >


์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๊ตฌ์กฐ์ฒด ์ƒ์„ฑ  

struct DoublyLinkedList<T: Equatable> {
    typealias Node = DoublyLinkedListNode<T>
    
    private var head = Node(data: nil)  // head๋ฅผ dummy ๋…ธ๋“œ๋กœ ์ƒ์„ฑ
    
    public var isEmpty: Bool {
        return head.next?.data == nil
    }
    
    public var first: Node? {
        return head.next
    }
}

 

ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ๋“ค์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „, ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•„์š”ํ•œ ํ”„๋กœํผํ‹ฐ๋“ค์„ ์„ ์–ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

(์ฝ”๋“œ ๊ตฌํ˜„๋ถ€๊ฐ€ ๊ธธ์–ด์ง€๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด typealias ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.)

 

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธ์„ ์œ„ํ•œ isEmpty์™€ ์ฒซ ๋…ธ๋“œ๋ฅผ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” first ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

head ๋…ธ๋“œ์˜ ๊ฒฝ์šฐ ์•ž์—์„œ ์„ค๋ช…ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ nil์„ ๊ฐ™๋Š” ๋”๋ฏธ ๋…ธ๋“œ๋กœ ์ƒ์„ฑ์„ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.


โญ๏ธsplice ๋ฉ”์„œ๋“œ: ์ž˜๋ผ๋‚ธ ํ›„ ์ด๋™ํ•˜๊ธฐ ์—ฐ์‚ฐ O(1)

์ฝ”๋“œ ์ž‘์„ฑ ์‹œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ตฌํ˜„๋ถ€์ž…๋‹ˆ๋‹ค.

 

์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ์˜ ๊ตฌํ˜„์„ ์‰ฝ๊ฒŒ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด splice ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•ด์ค๋‹ˆ๋‹ค.

 

splice(a, b, x) ์—ฐ์‚ฐ์€ ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ๋…ธ๋“œ a์™€ ๋…ธ๋“œ b์‚ฌ์ด์— ๋…ธ๋“œ๋“ค์„ ์ž˜๋ผ๋‚ด์„œ ๋…ธ๋“œ x ๋’ค์—  ๋ถ™์ด๋Š” ์—ฐ์‚ฐ์„ ๋œปํ•ฉ๋‹ˆ๋‹ค.

์ด ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•„์ˆ˜์ ์ธ ์กฐ๊ฑด 3๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์กฐ๊ฑด 1: a ๋…ธ๋“œ ๋‹ค์Œ์— b ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. (๋ฐ”๋กœ ์˜†์ด ์•„๋‹ˆ์–ด๋„ ์ƒ๊ด€์—†์Œ)
  • ์กฐ๊ฑด 2: a ๋…ธ๋“œ์™€ b ๋…ธ๋“œ ์‚ฌ์ด์— head(๋”๋ฏธ) ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์กฐ๊ฑด 3: a ๋…ธ๋“œ์™€ b ๋…ธ๋“œ ์‚ฌ์ด์— x ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

func splice(a: Node, b: Node, x: Node) {
    
    guard let aPrevious = a.previous, let bNext = b.next, let xNext = x.next else { return }
    
    // [a..b] ๊ตฌ๊ฐ„์„ ์ž˜๋ผ๋‚ด๊ธฐ
    aPrevious.next = bNext
    bNext.previous = aPrevious
    
    // [a..b]๋ฅผ x ๋‹ค์Œ์— ์‚ฝ์ž…ํ•˜๊ธฐ
    x.next = a
    a.previous = x
    b.next = xNext
    xNext.previous = b
}

moveAfter, moveBefore: splice๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋™ ํ•จ์ˆ˜ ์ •์˜  O(1)

moveAfter(a: Node, x: Node)๋Š” ๋…ธ๋“œ a๋ฅผ x ๋‹ค์Œ์œผ๋กœ ์ด๋™์‹œํ‚ค๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, splice ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์ˆ˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. 

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, moveBefore(a: Node, x: Node)๋Š” ๋…ธ๋“œ a๋ฅผ x ์ด์ „์œผ๋กœ ์ด๋™์‹œํ‚ค๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, splice ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์ˆ˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

// moveAfter ๋ฉ”์„œ๋“œ
func moveAfter(a: Node, x: Node) { // ๋…ธ๋“œ a๋ฅผ x ๋‹ค์Œ์œผ๋กœ ์ด๋™
    self.splice(a: a, b: a, x: x)
}

// moveBefore ๋ฉ”์„œ๋“œ
func moveBefore(a: Node, x: Node) { // ๋…ธ๋“œ a๋ฅผ x ์ด์ „์œผ๋กœ ์ด๋™
    guard let xPrevious = x.previous else { return }
    
    self.splice(a: a, b: a, x: xPrevious)
}

insertAfter, insertBefore: splice๋ฅผ ์ด์šฉํ•˜์—ฌ ์‚ฝ์ž… ํ•จ์ˆ˜ ์ •์˜  O(1)

insertAfter(data: T, x: Node)๋Š” data ๊ฐ’์„ ๊ฐ–๋Š” ์ƒˆ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋…ธ๋“œ x ๋’ค์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, moveAfter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์ˆ˜๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. 

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, insertBefore(data: T, x: Node)๋Š”  data ๊ฐ’์„ ๊ฐ–๋Š” ์ƒˆ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋…ธ๋“œ x ์•ž์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, moveBefore ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์ˆ˜์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

// insertAfter ๋ฉ”์„œ๋“œ
func insertAfter(data: T, x: Node) {
    moveAfter(a: Node(data: data), x: x)
}

// insertBefore ๋ฉ”์„œ๋“œ
func insertBefore(data: T, x: Node) {
    moveBefore(a: Node(data: data), x: x)
}

append, appendFirst: splice๋ฅผ ์ด์šฉํ•˜์—ฌ ์‚ฝ์ž… ํ•จ์ˆ˜ ์ •์˜  O(1)

append(data: T)๋Š” data ๊ฐ’์„ ๊ฐ–๋Š” ์ƒˆ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์ œ์ผ ๋’ค์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, insertBefore ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์ˆ˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. 

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, appendFirst(data: T)๋Š”  data ๊ฐ’์„ ๊ฐ–๋Š” ์ƒˆ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์ œ์ผ ์•ž์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, insertAfter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์ˆ˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

 

๋‘ ๋ฉ”์„œ๋“œ๋Š” head ๋…ธ๋“œ์˜ ์•ž, ๋’ค๋กœ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋…ธ๋“œ๋กœ ํ—ค๋“œ ๋…ธ๋“œ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

// append ๋ฉ”์„œ๋“œ
func append(data: T) {
    insertBefore(data: data, x: head)
    
    // insertBefore(data: data, x: head)๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ
    // guard let headPrev = head.previous else { return }
    // let newNode = Node(data: data)
    // self.splice(a: newNode, b: newNode, x: headPrev)
}

// appendFirst ๋ฉ”์„œ๋“œ
func appendFirst(data: T) {
    insertAfter(data: data, x: head)
    
    // insertAfter(data: data, x: head)๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ
    // let newNode = Node(data: data)
    // self.splice(a: newNode, b: newNode, x: head)
}

remove:  ์‚ญ์ œ ํ•จ์ˆ˜ O(1)

remove(x: Node)๋Š” x ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, x์˜ ์ด์ „ ๋ฐ ๋‹ค์Œ ๋…ธ๋“œ๋“ค์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐฑ์‹ ํ•˜๋ฏ€๋กœ ์ƒ์ˆ˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. (๋‹จ, x๋Š” head ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

// remove ๋ฉ”์„œ๋“œ
func remove(x: Node) -> Node? {
    if x == head {
        return nil
    }
    
    x.next?.previous = x.previous
    x.previous?.next = x.next
    return x
}

search:  ํƒ์ƒ‰ ํ•จ์ˆ˜ O(n)

search(data: T)๋Š” x ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์•„๊ฐ€๋ฏ€๋กœ ์ตœ์•…์˜ ๊ฒฝ์šฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด์— ๋น„๋ก€ํ•˜๋Š” ์„ ํ˜• ์‹œ๊ฐ„ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค.

// search ๋ฉ”์„œ๋“œ
func search(data: T) -> Node? {
    var node = head.next
    while node != head {
        if node?.data == data  {
            return node
        }
        node = node?.next
    }
    return nil
}

printList:  ์ถœ๋ ฅ ํ•จ์ˆ˜ O(n)

printList()๋Š” ๋ชจ๋“  ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋ฉฐ, ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜์—ฌ ๊ฐ ๋…ธ๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๋ฏ€๋กœ ์ตœ์•…์˜ ๊ฒฝ์šฐ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด์— ๋น„๋ก€ํ•˜๋Š” ์„ ํ˜• ์‹œ๊ฐ„ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค.

 

์ด ๋ฉ”์„œ๋“œ๋Š” ๊ตณ์ด ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฉฐ, ์ž˜ ๊ตฌํ˜„์ด ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

// printList ๋ฉ”์„œ๋“œ
func printList() {
    var current = head.next
    
    while let data = current?.data {
        print("\(data) -> ", terminator: "")
        current = current?.next
    }
    print("nil")
}

 


์ „์ฒด ์ฝ”๋“œ

// Node ์„ ์–ธ
class DoublyLinkedListNode<T: Equatable>: Equatable {
    static func == (lhs: DoublyLinkedListNode<T>, rhs: DoublyLinkedListNode<T>) -> Bool {
        return lhs === rhs
    }
    
    let data: T?
    var next: DoublyLinkedListNode?
    weak var previous: DoublyLinkedListNode?
    
    init(data: T?) {
        self.data = data
        self.next = self
        self.previous = self
    }
}

// ์ž๋ฃŒ ๊ตฌ์กฐ ์„ ์–ธ
struct DoublyLinkedList<T: Equatable> {
    
    typealias Node = DoublyLinkedListNode<T>
    
    private var head = Node(data: nil)
    public var isEmpty: Bool {
        return head.next?.data == nil
    }
    
    public var first: Node? {
        return head.next
    }
    
    // splice ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func splice(a: Node, b: Node, x: Node) {

        guard let aPrevious = a.previous, let bNext = b.next, let xNext = x.next else { return }

        aPrevious.next = bNext
        bNext.previous = aPrevious
        
        x.next = a
        a.previous = x
        b.next = xNext
        xNext.previous = b
    }
    
    // append ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func append(data: T) {
        insertBefore(data: data, x: head)
    }
    
    // appendFirst ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func appendFirst(data: T) {
        insertAfter(data: data, x: head)
    }
    
    // insertAfter ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func insertAfter(data: T, x: Node) {
        moveAfter(a: Node(data: data), x: x)
    }
    
    // insertBefore ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func insertBefore(data: T, x: Node) {
        moveBefore(a: Node(data: data), x: x)
    }

    // moveAfter ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func moveAfter(a: Node, x: Node) {
        self.splice(a: a, b: a, x: x)
    }
    
    // moveBefore ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func moveBefore(a: Node, x: Node) {
        guard let xPrevious = x.previous else { return }
        
        self.splice(a: a, b: a, x: xPrevious)
    }
    
    // search ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n)
    func search(data: T) -> Node? {
        var node = head.next
        while node != head {
            if node?.data == data  {
                return node
            }
            node = node?.next
        }
        return nil
    }
    
    // remove ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(1)
    func remove(x: Node) -> Node? {
        if x == head {
            return nil
        }
        
        x.next?.previous = x.previous
        x.previous?.next = x.next
        return x
    }
    
    // printList ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n)
    func printList() {
        var current = head.next
        while let data = current?.data {
            print("\(data) -> ", terminator: "")
            current = current?.next
        }
        print("nil")
    }
}

๋งˆ๋ฌด๋ฆฌ

์ƒ๊ฐ๋ณด๋‹ค ๊ธฐ๋กํ•˜๊ณ ์ž ํ•˜๋Š” ๋‚ด์šฉ๋“ค์ด ๋งŽ์•„์ ธ ๊ธ€์ด ๊ฝค ๊ธธ์–ด์ง„ ๊ฒƒ ๊ฐ™๋„ค์š”. ๐Ÿ˜… 

๊ทธ๋ž˜๋„ ์ด๋ ‡๊ฒŒ ๋ชจ๋“  ๋‚ด์šฉ์„ ๋‹ค๋ค„์„œ ๊ทธ๋Ÿฐ์ง€ ์ œ ๋จธ๋ฆฌ ์†์—๋„ ๋” ์ž˜ ๊ธฐ์–ต๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. 

(์ด ๊ธ€์„ ์ฝ๋Š” ๋ถ„๋“ค๋„ ๊ทธ๋žฌ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค!) 

 

๋ชจ๋“  ์ž๋ฃŒ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฅผ ์˜ฌ๋ฆฌ๊ณ  ์‹ถ์ง€๋งŒ, 

์ด๊ฒƒ์ €๊ฒƒ ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ๋“ค์ด ๋„ˆ๋ฌด ๋งŽ์•„ ๊ณ„์†ํ•ด์„œ ํ›„์ˆœ์œ„๊ฐ€ ๋˜๋‹ค๊ฐ€ ์ด์ œ์„œ์•ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์— ๊ด€ํ•ด ์ž‘์„ฑ์„ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. 

์•ž์œผ๋กœ ๊ธฐ๋กํ•  ์ž๋ฃŒ๊ตฌ์กฐ๋“ค์ด ๋งŽ์ง€๋งŒ ๋น ๋ฅธ ์‹œ์ผ ๋‚ด์— ๋‹ค ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค! 

 

๋งˆ์ง€๋ง‰์œผ๋กœ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ์•Œ๊ฒŒ๋œ ์‚ฌ์‹ค์ธ๋ฐ 

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ํ…์ŠคํŠธ ์—๋””ํ„ฐ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. 

 

์—๋””ํ„ฐ์˜ ์ปค์„œ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ €์žฅํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ๋‹จ์ ์ธ ํƒ์ƒ‰ ๊ณผ์ •์ด ํ•„์š”๊ฐ€ ์—†์–ด์ง€๊ณ , 

๋น ๋ฅธ ์‹œ๊ฐ„์— ์ž์‹ ์ด ์›ํ•˜๋Š” ๊ธ€์ž(์ปค์„œ)๋ฅผ ์‚ญ์ œ ๋˜๋Š” ์‚ฝ์ž…์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 

 

์ด์ƒ์œผ๋กœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ํฌ์ŠคํŒ…์„ ๋งˆ์น˜๊ฒ ์Šต๋‹ˆ๋‹ค!!

 

์ž˜๋ชป๋œ ๋‚ด์šฉ์ด๋‚˜ ๊ถ๊ธˆํ•˜์‹  ์ ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€ ๋‚จ๊ฒจ์ฃผ์„ธ์š”. ๐Ÿค“

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


๐Ÿ“ ์ฐธ๊ณ  ์ž๋ฃŒ

ํ•œ๊ตญ์™ธ๋Œ€ ์‹ ์ฐฌ์ˆ˜ ๊ต์ˆ˜๋‹˜์˜ Data Structures with Python ๊ฐ•์˜

์œ„ํ‚ค ๋ฐฑ๊ณผ: ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ

https://jeong9216.tistory.com/401

https://opentutorials.org/module/1335/8821