접근 속도:
배열은 인덱스를 통해 데이터에 접근할 수 있으므로, 데이터의 조회가 O(1)의 시간복잡도로 매우 빠르게 이루어집니다. 이러한 특성은 특정 위치의 데이터를 빈번히 조회해야 하는 경우에 유용합니다.
간결성:
배열은 다른 복잡한 자료구조에 비해 구현이 간단하고 이해하기 쉽습니다. 초기화도 간단히 할 수 있고, 다루기도 편리합니다.
메모리 사용:
연결 리스트와 같은 다른 자료구조에 비해, 배열은 더 적은 메모리를 사용합니다. 배열은 노드간의 참조를 저장할 필요가 없기 때문에, 메모리 오버헤드가 적습니다.
Cache Locality:
배열은 데이터를 연속적인 메모리 영역에 저장하므로, CPU 캐시의 효율성이 높아집니다. 이로 인해 배열은 다른 자료구조에 비해 성능이 향상될 수 있습니다.
다목적 사용:
배열은 정렬, 검색 등 다양한 알고리즘에서 기본적으로 사용되며, 다른 복잡한 자료구조의 구성 요소로도 사용될 수 있습니다.
안정성과 예측가능성:
배열은 고정된 크기를 가지므로, 런타임 중에 크기가 변하지 않습니다. 이러한 특성은 예기치 않은 메모리 문제를 방지할 수 있습니다.
물론 배열도 단점이 있습니다. 배열의 크기는 고정되어 있어, 런타임에 크기를 변경할 수 없으며, 이로 인해 메모리 낭비가 발생할 수 있습니다. 또한, 삽입과 삭제 연산이 O(n)의 시간복잡도를 가지므로, 중간에 데이터를 삽입하거나 삭제할 경우 비효율적입니다.
이러한 장점과 단점을 고려할 때, 배열은 간단하고 효율적인 자료구조로서, 많은 상황에서 유용하게 사용될 수 있습니다.
문자열 역순 변환:
문자열을 스택에 하나씩 넣고, 모든 문자가 스택에 들어간 후에 하나씩 꺼내어 새 문자열을 생성하면, 원래 문자열의 역순이 만들어집니다.
괄호 검사:
프로그래밍에서 괄호가 올바르게 닫혀있는지 확인할 때 스택을 사용합니다. 여는 괄호를 만나면 스택에 푸시하고, 닫는 괄호를 만나면 스택에서 팝합니다.
수식의 후위 표기법 변환 및 계산:
중위 표기법의 수식을 후위 표기법으로 변환하거나, 후위 표기법의 수식을 계산할 때 스택을 사용합니다.
웹 브라우저의 뒤로 가기 기능:
웹 브라우저에서 방문한 페이지들을 스택에 저장하여 뒤로 가기 기능을 구현합니다.
프린터 대기열:
여러 문서를 차례대로 인쇄할 때, 프린터 대기열에 문서들이 큐의 형태로 저장됩니다.
프로세스 스케줄링:
운영체제에서 여러 프로세스를 관리할 때, 프로세스들은 준비 큐에 저장되어 차례대로 CPU를 할당받습니다.
은행 대기열:
은행에서 고객들이 차례대로 서비스를 받기 위해 대기하는 구조로 큐를 사용합니다.
너비 우선 탐색 (BFS) 알고리즘:
그래프 탐색 알고리즘 중 하나인 너비 우선 탐색(BFS)에서 방문해야 할 노드들을 저장하는데 큐를 사용합니다.
스택과 큐는 데이터의 저장과 접근 방식이 다릅니다. 스택은 후입선출(LIFO) 방식으로, 마지막에 들어온 데이터가 먼저 나갑니다. 반면, 큐는 선입선출(FIFO) 방식으로, 먼저 들어온 데이터가 먼저 나갑니다.
메모리 구조:
크기:
접근 시간:
삽입/삭제:
메모리 사용량:
캐시 지역성:
빈번한 조회:
인덱스를 이용해 원소에 빠르게 접근할 필요가 있는 경우, 예를 들어, Lookup 테이블이나 해시 테이블의 내부 구현 등에 사용됩니다.
메모리 크기가 고정:
크기가 고정된 데이터 집합을 다룰 때 사용하며, 예를 들어, 행렬 연산에서 사용됩니다.
빈번한 삽입/삭제:
중간에 데이터를 자주 삽입하거나 삭제해야 하는 경우, 예를 들어, 동적 메모리 관리에 사용됩니다.
크기가 동적으로 변하는 경우:
데이터의 개수가 미리 알려지지 않고, 동적으로 변할 때 사용합니다, 예를 들어, 스택이나 큐의 구현에 사용될 수 있습니다.
배열과 링크드 리스트는 각각의 용도에 따라 적합하며, 상황과 요구사항에 따라 적절한 자료구조를 선택해야 합니다.
해시테이블은 키-값 쌍을 저장하는 자료구조입니다. 해시테이블의 주요 구성요소는 다음과 같습니다.
해시 함수는 키를 받아서 고정된 크기의 정수(배열 인덱스)로 변환합니다. 그리고 이 인덱스는 해시테이블에서 값이 저장되거나 조회되는 위치를 결정합니다. 그러나 서로 다른 키가 같은 인덱스로 해시될 때 충돌이 발생합니다. 이를 해결하기 위한 여러 전략이 있습니다.
체이닝(Chaining):
체이닝 방식에서는 하나의 버킷에 여러 개의 키-값 쌍을 저장할 수 있습니다. 각 버킷은 연결 리스트로 구현되며, 충돌이 발생하면 연결 리스트에 노드를 추가합니다. 체이닝은 구현이 간단하고, 테이블의 로드 팩터가 1을 초과해도 동작합니다. 그러나 메모리 오버헤드가 크고, 캐시 효율성이 떨어질 수 있습니다.
오픈 어드레싱(Open Addressing):
오픈 어드레싱에서는 모든 키-값 쌍이 해시테이블 자체에 저장됩니다. 충돌이 발생하면 다른 버킷에 키-값 쌍을 저장합니다. 오픈 어드레싱에는 여러 방법이 있습니다:
해시테이블은 키-값 쌍을 효율적으로 저장하고 조회할 수 있는 자료구조입니다. 해시 함수를 사용하여 키를 배열 인덱스로 변환하며, 충돌이 발생할 경우 체이닝이나 오픈 어드레싱 같은 방법으로 해결할 수 있습니다.
우선순위 큐는 각 요소가 우선순위를 가진 데이터의 컬렉션으로, 우선순위가 가장 높은 요소가 가장 먼저 삭제됩니다. 일반적으로 우선순위 큐는 이진 힙(Binary Heap), 피보나치 힙(Fibonacci Heap), 또는 다른 자료구조를 사용하여 구현됩니다. 시간복잡도는 사용하는 자료구조에 따라 다르게 됩니다.
이진 힙에서는 다음과 같은 시간복잡도를 가집니다:
피보나치 힙에서는 아래와 같은 시간복잡도를 보입니다:
배열이나 연결 리스트를 사용하여 우선순위 큐를 구현할 경우 다음과 같은 시간복잡도를 가집니다:
이진 힙은 삽입과 삭제에서 로그 시간복잡도를 제공하면서도 구현이 상대적으로 간단하여, 우선순위 큐를 구현할 때 널리 사용되는 자료구조입니다. 그러나 피보나치 힙과 같은 더 고급 자료구조는 특정 상황에서 더 나은 성능을 제공할 수 있습니다.