=> 2019.07.28 : ๋์ฒด ์ด๊ฑธ ์ด๋ป๊ฒ ํ ์ฑํฐ์ ์ ๋ฆฌํ๊ฒ ๋ค๊ณ ๋ชฐ์๋ฃ์๋์ง...ํํ๊ฐ...๐ญ
์ค๋์ Data Structrue์ ๋ํด์ ์ค์ค๋ก ์์๋ณด๊ณ ๊ณต๋ถํด์ผํฉ๋๋ค!
๋จผ์ , ์์๋๋ก ๊ฐ์๋ด์ฉ์ ์ ๋ฆฌํ๊ณ ๊ณต๋ถํด๋ด ์๋ค! ๐
์์์ ์คํ์ ๋๋ค. ๋ฒ์ญํ๋ฉด ์๋ค. ์๋ค์ฌ๋ฆฌ๋ค. ๊ทธ๋ฐ ๋๋์ด์ฃ .
์ด๊ฒ ๊ทธ๋ฆผ์ผ๋ก ๋ณด๋ฉด ์ ๋ง ๊ฐ๋จํฉ๋๋ค. (์ฒ์์ด๋ผ ํ๋ฒ ๊ทธ๋ ค๋ดค์ต๋๋ค...๐คซ)
๋ฒํธ๋๋ก ์์๋๋ก ๋ค์ด๊ฐ๊ณ (PUSH), ์ ์ผ ์์์ ๋ถํฐ ๊บผ๋ผ ์ ์์ต๋๋ค.(POP)
์ด๋ฐ๊ฑธ ๋ฉ์๊ฒ LIFO(Last In First Out) ์ด๋ผ๊ณ ํฉ๋๋ค!
๋์์ ๋ณด๋ฉด JavaScript์์ Array๋ฉ์๋์ธ Push์ Pop์ด ์คํ ์ฉ์ด์ ๋์ผํฉ๋๋ค!
์ฝ๋๋ก ๊ฐ๋จํ ์์๋ฅผ ๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
// 1.
const add = (a, b) => a + b;
// 2.
const printNumber = (x, y) => {
let num = add(x, y);
return num;
}
// 3.
printNumber(5, 10) // 15
printNumber
๊ฐ ๋จผ์ ์ฝ์คํ์ ๋ค์ด๊ฐ๋๋ค.(PUSH)add
ํจ์๋ฅผ ํธ์ถํ๋ฏ๋ก add
ํจ์๊ฐ ์ฝ์คํ์ ๋ค์ด๊ฐ๋๋ค.(PUSH)num
์ ๊ณ์ฐํ๊ณ ๋๋ฉด add
๊ฐ ์ฝ์คํ์์ ๋น ์ ธ๋์ต๋๋ค.(POP)printNumber
๊ฐ ์ฝ์คํ์์ ๋น ์ ธ๋์ต๋๋ค.(POP)๊ทธ๋ผ ์ด์ ๊ฐ๋ตํ๊ฒ ๊ตฌํํด๋ด ์๋ค!
๋จผ์ pseudo Code
๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค!
์ฌ์ค ์ฒ์์ด๋ค๋ณด๋ pseudo Code๋ผ๊ธฐ๋ณด๋จ ์์๋ง ์ ์ ๊ฒ์ ๊ฐ๊น์ต๋๋ค.
/* pseudo Code */
1. Stack ๊ป๋ฐ๊ธฐ ์์ฑ
2. ๋น ๋ฐฐ์ด์ ์์ฑ
3. PUSH ๊ตฌํ -> arr.push(item)
4. POP ๊ตฌํ -> arr.pop()
5. size ๊ตฌํ -> ๋ฐฐ์ด์ ๊ธธ์ด
์ค์ ์ฝ๋๋ ์์ ์ ์งํํ๊ณ ์์ฑํ์์ต๋๋ค.
psuedo Code์๋ ๋ค๋ฅด๊ฒ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ผ ํ์ ์๋น ๋ถ๋ถ ๋ณ๊ฒฝํ์์ต๋๋ค.
์ค๋ช ์ ์ฃผ์์ด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค :)
// Stack
const Stack = function () {
// 1. ๋ฉ์๋๋ฅผ ๋ด์ ์ธ์คํด์ค ๊ฐ์ฒด, ์ ์ฅ์, ์นด์ดํธ๋ฅผ ์ ์ธํฉ๋๋ค.
const someInstance = {};
const storage = {};
var count = 0;
// 2. PUSH ๋์ : storage์ {count, value} ๊ฐ์ผ๋ก ์ถ๊ฐํ๊ณ , count++
someInstance.push = function (value) {
storage[count] = value;
count++;
};
// 3. POP ๋์ : ๊ฐ์ด ์กด์ฌํ ๋, storage์์ key์ ๋ง์ถฐ ์ง์ฐ๊ณ , ๊ทธ ๊ฐ์ ๋ฆฌํดํฉ๋๋ค.
someInstance.pop = function () {
if (count > 0) {
count--;
let popNumber = storage[count];
delete storage[count];
return popNumber;
} else {
return undefined
}
};
// 4. SIZE ๋์ : count๋ฅผ ์ฌ์ฉํ์ฌ ํฌ๊ธฐ๋ฅผ ํ์ธํฉ๋๋ค.
someInstance.size = function () {
return count;
};
return someInstance;
};
์ด๋ฒ์ ๊ฐ์ฒด์ prototype์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
์ ๊ฐ ๋๋ผ๊ธฐ์ ๋ ์ง๊ด์ ์ด๊ณ ๊ฐํธํฉ๋๋ค :)
๊ฐ ๊ฐ์ฒด์ prototype์ ์ง์ ๊ตฌํํ๋ฉด ๋๋๊น์!
// 1. Stackํด๋์ค์ store(์ ์ฅ์)์ count ๋ณ์๋ฅผ ์์ฑํ๋ค.
const Stack = function() {
this.store = {};
this.count = 0;
};
// 2. Stack๊ฐ์ฒด์ prototype์ push๋ฉ์๋๋ฅผ ๊ตฌํํ๋ค.
Stack.prototype.push = function(item){
this.store[this.count] = item;
this.count++;
};
// 3. Stack๊ฐ์ฒด์ prototype์ pop๋ฉ์๋๋ฅผ ๊ตฌํํ๋ค.
Stack.prototype.pop = function() {
if (this.count <= 0) return undefined;
this.count--;
let popNumber = this.store[this.count];
delete this.store[this.count];
return popNumber;
};
// 4. Stack๊ฐ์ฒด์ prototype์ size๋ฉ์๋๋ฅผ ๊ตฌํํ๋ค.
Stack.prototype.size = function() {
return this.count;
}
์คํ๊ณผ ํญ์ ๊ฐ์ด ์ธ๊ธ๋๋ ํ ์ ๋๋ค.
์คํ๊ณผ ๋ค๋ฅธ ์ ์ด๋ผ๋ฉด ์์ผ๋ก ๋์ฌ ์ ์๋ ์ ํ์ด๋ผ๋ ๊ฒ๋๋ค!
PUSH๋์์ enqueue์ด๊ณ , POP๋์์ SHIFT๋ก ๋ฐ๋๊ณ , dequeue๋ผ๊ณ ํฉ๋๋ค.
๋จผ์ enqueueํ ๊ฒ์ด ๋จผ์ dequeue๋์ด, FIFO(First In First Out)์ด๋ผ๊ณ ํฉ๋๋ค.
์ ํฌ๊ฐ ๋ง๋ค ํ์์๋ head์ tail์ ๊ตฌํํ ๊ฒ์ ๋๋ค.
enqueue์์๋ ๊ฐ ๋ ธ๋์ tail์ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๋์ง๋ง,
dequeue์์๋ tail์ด ์๋ head์ ๊ฐ์ ์ง์์ผ ํ๊ธฐ ๋๋ฌธ์ด์ฃ !
์ค์ ์ฝ๋๋ฅผ ๋ณด์๋ฉด ๋ ์ดํด๊ฐ ์ฌ์ธ ๊ฒ๋๋ค.
์คํ๋์ฒ๋ผ psuedo Code
๋ฅผ ๋จผ์ ์์ฑํด๋ด
์๋ค!
/* psuedo code */
1. ํ ๊ป๋ฐ๊ธฐ ์์ฑ
2. ๋น ๋ฐฐ์ด ์์ฑ
3. enqueue ๊ตฌํ -> arr.push(item)
4. dequeue ๊ตฌํ -> arr.shift()
5. size ๊ตฌํ -> arr.length()
๊ทธ๋ผ ์ ๋ ผ๋ฆฌ์ ๋ง์ถ์ด ํ๋ฅผ ๊ตฌํํด ๋ด ์๋ค!
ํ๋ ์คํ๊ณผ ๋ค๋ฅด๊ฒ pop
๋์ shift
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค!
๋ง์ฐฌ๊ฐ์ง๋ก, ์์ ์ดํ ์ฝ๋๋ฅผ ์ถ๊ฐํ์๊ณ , ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ฒ ๋์์ต๋๋ค.
// Queue
const Queue = function () {
// 1. ํ์ ์กฐ๊ธ ๋ค๋ฆ
๋๋ค. ์ฒ์๊ณผ ๋์ผ๋ก head์ tail์ ์ฌ์ฉํฉ๋๋ค.
const someInstance = {};
const storage = {};
var head = 0;
var tail = 0;
var count = 0;
// 2. enqueue ๋์ : storage์ ๋ง์ง๋ง์ ๋ปํ๋ {tail, value}์ ์ถ๊ฐํฉ๋๋ค.
someInstance.enqueue = function (value) {
storage[tail] = value;
tail++;
count++;
};
// 3. dequeue ๋์ : ๊ฐ์ด ์กด์ฌํ ๋, ๋งจ ์์ ๋ปํ๋ {head, value}๋ฅผ ์ญ์ ํ๊ณ ๋ฆฌํดํฉ๋๋ค.
someInstance.dequeue = function () {
if (count > 0) {
// storage[head]์ ๊ฐ์ ๊ธฐ์ตํ์ฌ ๋ฆฌํดํ๊ธฐ ์ํด์ ๋ฐ๋ก ๋ณ์๋ก ์ ์ธํ์์ต๋๋ค.
let headNumber = storage[head];
delete storage[head];
head++;
count--;
return headNumber;
}
};
// 4. size ๋์ : count๋ฅผ ์ฌ์ฉํ์ฌ ํฌ๊ธฐ๋ฅผ ํ์ธํฉ๋๋ค.
someInstance.size = function () {
return count;
};
return someInstance;
};
์ฝ๋๋ง ๋ณด๋ฉด ์ดํดํ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
์๋์ ์์์ ๋ฐ๋ผ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐ๋ผ๊ฐ๋ณด์ธ์!! โฝ๏ธ...
/* ์งํ๊ณผ์ . storage */
1. enq('a') : head: 0, tail: 0 {0: 'a'}; / ์ดํ head: 0, tail: 1
2. enq('b') : head: 0, tail: 1 {0: 'a', 1: 'b'}; / ์ดํ head: 0, tail: 2
2. deq() : head: 1, tail: 2 {1: 'b'}; / ์ดํ head: 1, tail: 2
2. deq() : head: 2, tail: 2 {}; / ์ดํ head: 2, tail: 2
const Queue = function() {
// Hey! Rewrite in the new style. Your code will wind up looking very similar,
// but try not not reference your old code in writing the new style.
this.storage = {};
this.head = 0;
this.tail = 0;
this.count = 0;
};
Queue.prototype.enqueue = function (value) {
this.storage[this.tail] = value;
this.tail++;
this.count++;
}
Queue.prototype.dequeue = function () {
if (this.count > 0) {
let headNumber = this.storage[this.head];
delete this.storage[this.head];
this.head++;
this.count--;
return headNumber;
}
}
Queue.prototype.size = function () {
return this.count;
}
์ฐ๊ฒฐ๋ฆฌ์คํธ๋ ์ฌ๋ฌ ๊ฐ์ ๋ ธ๋๋ก ๊ตฌ์ฑ๋์ด ํ ์ค๋ก ์ฐ๊ฒฐ๋์ด ์๋ ๋ฐฉ์์ ๋๋ค!
๊ฐ ๋ ธ๋๋ ๋ฐ์ดํฐ์ ๋ค์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฃผ์๋ฅผ ๊ฐ์ง๊ณ ์๊ตฌ์.
์ฐ๊ฒฐ๋ฆฌ์คํธ๋ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐ, ์ญ์ , ํ์ ๋ฑ์ ํ ์ ์์ต๋๋ค.
์ ํฌ๋ ์ถ๊ฐ, ์ญ์ , ํฌํจ์ ๋ฌด ๋ฅผ ๊ตฌํํด๋ณผ ๊ฒ์ ๋๋ค.
์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ฅผ ์ฝ๊ฒ ๋งํ๋ฉด 1->2->3->4->5 ์์๋ก ์ฐ๊ฒฐ๋์ด ์๋ค๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.
์ ์ค๋ช ๋ง ๋ณด๋ฉด ๋ฐฐ์ด๊ณผ ๋์ผํ๋ค๋ ๊ฒ์ ์ ์ ์๋๋ฐ์!
๊ฑฐ์ ๋น์ทํ์ง๋ง, ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ง์ ์ฅ์ ์ด ์์ต๋๋ค!
[1, 2, 4, 5] ๋ผ๋ ๋ฐฐ์ด์ ์์์ ๋ง๊ฒ 3์ ์ง์ด ๋ฃ๋๋ค๋ฉด,
3์ด ๋ค์ด๊ฐ๋ฉด์ ์ธ๋ฑ์ค๊ฐ 2๊ฐ ๋๊ณ , 4์ 5์ ์ธ๋ฑ์ค๊ฐ ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค.
ํ์ง๋ง ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ์ถ๊ฐ์์๋ ์ฐ๊ฒฐํ ์์น์ ์,๋ค ๋ ธ๋์ ์ฐ๊ฒฐํ๋ฉด ๋ฉ๋๋ค.
๋ฌผ๋ก , ๋จ์ ๋ ์์ต๋๋ค.
์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ ํ์์ ์ํด ์ฒซ๋ฒ์งธ๋ถํฐ ํ์ํ๋ฏ๋ก ์ํฉ์ ๋ฐ๋ผ ๋๋ ค์ง ์ ์์ต๋๋ค.
๋ฐ๋ผ์, ๋ฐ์ดํฐ ์ถ๊ฐ์ ์ญ์ ๊ฐ ๋ง์ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๊ฒ ์ฃ ? ๐๐ป
๊ทธ๋ฆฌ๊ณ , ๋ฆฌ์คํธ์ ์ข ๋ฅ๋ ์ด 4๊ฐ์ง๊ฐ ์๋๋ฐ์,
์ค๋์ 1๋ฒ, ๋จ์ผ ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋ํด์๋ง ์์๋ณด๊ฒ ์ต๋๋ค. โ๐ป
psuedo Code
๋ถํฐ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
/* psuedo Code */
1. Node ์์ฑ ( Include data & addr)
2. LinkedList ๊ป๋ฐ๊ธฐ ์์ฑ
3. ๋น์ด์๋ head, tail ์์ฑ
4. insert ๊ตฌํ
5. remove ๊ตฌํ
6. contain ๊ตฌํ
๊ณผ์ ๋ฅผ ์๋ฃ ํ๊ณ ๋ ๋ค์ ์์ ํ๊ณ ์์ต๋๋ค.
์ pseudoCode์๋ ๋ค๋ฅผ ์ ์์ต๋๋ค.
๊ฐ ์ฝ๋์ ๋ํ ์ค๋ช
head : ๊ฐ ๋ ธ๋์ ๋จธ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ head์ ๋๋ค.
tail : ๊ฐ ๋ ธ๋์ ๊ผฌ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ tail์ ๋๋ค.
addToTail : ์ ๋ ธ๋๋ฅผ ์์ฑํ๊ณ , tail์ ์ ๋ฌด์ ๋ฐ๋ผ newNode๋ฅผ ์กฐ๊ฑด์ ๋ง์ถฐ ๋์ ํฉ๋๋ค.
removeHead : tmp์ ์ ๊ฑฐํ๋ ค๋ head๋ฅผ ์ ์ฅํ๊ณ , head์ next๋ฅผ head์ ๋ฎ์ต๋๋ค.
contain : target๊ณผ ์ผ์นํ๋ ๊ฐ์ด ๋์ฌ๋ ๊น์ง head์ next์ head๋ฅผ ๋ฎ์ต๋๋ค.
insert๋์๋ง ์ดํดํ์๋ฉด ๋๋จธ์ง ๊ฐ๋จํ ๋ฏ ํฉ๋๋ค.
์ค๋ช ๋ณด๋ค๋ ์ฝ๋ ๋ณ ์ฃผ์์ด ๋ ์ดํด๊ฐ ์ฌ์ธ ๊ฒ ๊ฐ์ต๋๋ค!
// LinkedList
const LinkedList = function() {
const list = {};
list.head = null;
list.tail = null;
list.addToTail = function(value) { // * INSERT ๋ฉ์๋
var newNode = new Node(value); // * ์๋ก์ด ๋
ธ๋ ์์ฑ
if (!list.tail) { // * list๊ฐ ๋น์๋ค๋ฉด list์ tail์ ์ ๋
ธ๋ ์์ฑ
list.tail = newNode; // * list.tail์ Node1์ ๊ฐ๋ฆฌํต๋๋ค. head์ ๋์ผํฉ๋๋ค.
list.head = newNode; // * ํ์ฌ ์ํ : list { head === tail { Node1 { next: null, value } } }
} else { // *
list.tail.next = newNode; // * tail์ Node2์ ์ฃผ์(null)๋ก Node3์ ๊ฐ๋ฆฌํด.
list.tail = newNode; // * tail์ Node3์ผ๋ก ๋์ฒด.
}
};
// ! ์ถ๊ฐ ์ค๋ช
: ์๋ ์์๋ฅผ ๋ณด๋ฉด, ์ดํด์ ๋์์ด ๋ฉ๋๋ค. ์ list์ head์ tail๋ง ์กด์ฌํ๋์ง์ ๋ํด ์ค๋ช
ํฉ๋๋ค.
// 1. ๋ง์ฝ addToTail(5)์ (10)์ ํ์๋ค๊ณ ํ๋ฉด, ์๋์ ๊ฐ์ต๋๋ค.
// list: { head { value: 5, next: { value: 5, next: null } } , tail { value: 10, next: null } }
// 2. ์ฌ๊ธฐ์ addToTail(15)๋ฅผ ์ถ๊ฐํ๋ค๋ฉด,
// list: { head { value: 5, next: { value: 10, next: null } } , tail { value: 15, next: null } }
// ์ list์์ head์ next๋ฅผ ๋ณด์๋ฉด 1๋ฒ์์์ tail์ ๊ฐ๋ฆฌํค๊ณ ์์ต๋๋ค.
// ์ฆ, ์๋์ contain์ผ๋ก target์ ํ์ธํ ๋, head.next๋ฅผ ํ๊ณ ํ๊ณ ํ๊ณ ๋ค์ด๊ฐ๋ฉด
// list.head.next.next === list.tail (==> { value: 15, next: null }) ์ด ๋๋ ๊ฒ์
๋๋ค.
list.removeHead = function() { // REMOVE FIRST NODE
if(!list.tail) return;
let tmp = list.head;
let removed = tmp.value;
list.head = list.head.next;
return removed;
};
list.contains = function(target) { // SEARCH, but return true/false
if (!list.tail) return undefined;
let tmp = list.head;
while(tmp.value !== target) {
tmp = tmp.next;
if (!tmp) return false;
}
return true;
};
return list;
};
const Node = function(value) {
const node = {};
node.value = value;
node.next = null;
return node;
};