스택은 FILO(First In Last Out)
구조로 가장 먼저 들어온 데이터가 가장 나중에 나가고, 가장 나중에 들어온 데이터가 가장 먼저 나갑니다.
즉 입력방향과 출력방향이 한 방향인 방향이 동일한 선형 자료구조
입니다. Stack을 구현할때 꼭 정해진 것은 아니지만, 관례상 Stack에 데이터를 입력하는 것을 push
, 데이터를 출력하는 것을 pop
이라고 부릅니다. 다수의 데이터를 한번에 또는 임의의 위치에 데이터를 입출력 할 수 없습니다.
스택은 브라우저의 앞뒤로 뒤로가기, 실행취소, 동전꽂이등에 사용될 수 있습니다.
큐는 FIFO(First In First Out)
구조로 가장 먼저 들어온 데이터가 가장 먼저 나가고, 가장 나중에 들어온 데이터가 가장 나중에 나갑니다.
입력과 출력 방향이 상반된 방향인 방향이 다른 선형 자료구조
입니다. Queue를 구현할 때 데이터를 입력하는 것을 Enqueue
데이터를 출력하는 것을 Dequeue
라고 관례상 부릅니다. 스택과 마찬가지로 다수의 데이터를 한번에 또는 임의의 위치에 데이터를 입출력 할 수 없습니다.
큐는 순서대로 처리해야할 줄서기, 버퍼, 게임서칭 등 스택보다 더 많은 분야에서 활용 될 수 있습니다.
디큐는 FIFO
와 LIFO
의 성질을 모두 가지고 있습니다.
입력과 출력의 방향을 그때마다 선택하여 같을 수도, 다를 수도 있습니다. 큐에서 입력을 offer
, 출력을 poll
이라고 한다면,
메서드 | 설명 |
---|---|
offerFirst | 데이터를 맨 앞에 입력 |
offerLast | 데이터를 맨 마지막에 입력 |
pollFirst | 맨 앞의 데이터를 출력 |
pollLast | 맨 마지막의 데이터 출력 |
메서드로 처음과 마지막에 각각 입력과 출력이 가능합니다.
다만 주의해야할 점은 양 끝단에서 각각 입력과 출력이 모두 가능하지만, 다수의 데이터를 한번에 또는 임의의 위치에 데이터를 입출력 할 수는 없습니다.
LinkedList
는 배열과 기능은 동일하나 작동방식과 구성에서 차이가 존재합니다.
우선 배열은 물리적 메모리 내에서 연속적으로 배치되어 쉽고 빠르게 요소에 접근가능하나 배열의 크기를 조절할 수도 없습니다.
반면 LinkedList
는 메모리에 비 연속적으로 배치되어 인덱스가 아닌 다음 노드의 주소값으로 다음 요소의 값을 확인합니다. 이를 위해서는 노드는 데이터와 다음 노드를 가리키는 주소가 필요합니다.
배열과 LinkedList
는 메모리내에 어떻게 구성되고 요소를 어떻게 탐색하는지 다르므로 탐색, 삽입, 삭제에서 상당히 상이합니다.
O(1)
이지만 LinkedList
의 경우 첫 노드부터 다음노드의 주소를 따라 가야하므로 O(n)
만큼 걸립니다.1칸씩 뒤로 이동
해야 삽입할 자리가 생길 것입니다 따라서 O(n)
. 반면 LinkedList는 연속되어 저장됨을 보장하지 않으므로 삽입 하려는 노드를 아무곳에나 만들고 삽입 노드 자신의 Link
와 바로 이전 노드의Link
만 수정하면 됩니다 O(1)
.1칸씩 앞으로 이동
해야 하므로 O(n)
이 필요합니다. LinkedList는 이전노드의 주소만 삭제하려는 노드를 건너띄고 다음 노드의 주소를 가리키면 되므로O(1)
만큼 걸립니다.탐색에 있어 배열이 시간을 덜 사용하고, 수정과 삭제는 LinkedList가 시간을 덜 사용 합니다. 따라서, 수정, 삭제가 빈번하지 않은 자료는 배열을 수정과 삭제가 빈번히 발생하는 자료는 LinkedList가 유리합니다.
HashTable
은 Map
인터페이스를 구현한 컬랙션 클래스입니다. 기본적으로 (키,값)쌍으로 이루어져 있으며 Hash를 이용합니다.
길이와 크기가 다양한 키
들을 해시함수(hash Function)
를 사용해 변환한 해시(hash)
를 인덱스로 삼아 키와 값의 쌍들을 저장합니다.
인덱스 = (KA mod 1)m
, 숫자로된 키 K, 0과 1사이 실수 A, 2의 제곱수인 m해시충돌이란? 키값이 다르지만, 해시함수를 거치면서 나온 해시값이 같을때 이를 처리하는 방법입니다.
보통 개방연결법과 분리연결법, 저장소 확장이 존재합니다.
1
-> 4
-> 9
-> 16
연결리스트 LinkedList
나 트리 Red-Black Tree)
등의 자료구조를 이용해 여러개의 데이터를 저장하는 방법HashMap
이 저장소 확장 방식을 채택중이며 75%이상 사용시 크기를 2배로 늘립니다.이전의 Stack, Queue, Deque, LinkedList는 자료가 입력되는 순서에 따라 결정이 되었지만 heaptree는 데이터의 크기에 따라 정렬되기 때문에 순번이 아닌 우선순위에 따라 선택하는 알고리즘에 효과적입니다.
자기자신보다 작은 값과 큰값을 엄격히 구분하던 이진트리와 다르게 HeapTree
는 상대적으로 느슨하게 정렬됩니다. 데이터 입력시 자기자신과 부모노드만 비교하기 때문에 트리 전체적으로 볼땐 형제 노드간 비교를 할 수 없습니다.
또 힙트리는 완전 이진트리 구조를 가지는데, 데이터 입력시 항상 마지막 노드에 추가 되므로 항상 완전 이진트리를 유지할 수 있습니다.
Min HeapTree는 부모노드와 작은지 비교합니다.
Min HeapTree는 자녀간, 자녀와 더 큰지 비교합니다.
HeapTree는 입력과 삭제시 마지막 노드를 이동시킵니다. 따라서 항상 완전이진 트리를 유지할 수 있습니다. 완전 이진트리는 루트노드 ~ 마지막 리프노드 까지 빈 공간이 없이 꽉 차 있기 때문에 배열로 표현이 가능합니다.
코딩테스트, 자료구조 활용을 위해서 Stack,Queue,LinkedList,Tree,Hash등등 파생형들을 포함하여 어떤 원리로 동작하는지 이해하는것이 중요합니다. 또 자바에서는 어떤 컬렉션 프레임워크로 해당 자료구조들을 제공하고 있는지 찾아 보겠습니다.
https://github.com/ds02168/CodeStates/tree/main/src/JAVA_DataStructure