ADT(Abstract Data Type)
- 프로그래밍을 하면서 데이터 처리를 위한 자료형이 존재한다.
- 파이썬에서 프로그래밍을 위한 도구인 기본자료형(숫자, 문자열, 리스트, 딕셔너리 등)이 있다.
- ADT는 추상적으로 필요한 기능을 나열한 일종의 명세서(로직)이다.
- 기본자료형을 활용하여 사용자에 의해 구현된다.
abstract
는 소프트웨어가 발전하면서 프로그램의 크기나 복잡도가 같이 증가하였고 프로그램의 핵심부분을 간단하게 설명하기 위해 생겨났다.
연결리스트(linked-list)
- 데이터를 노드의 형태로 저장한다.
- 노드에는 데이터와 다음 노드를 가르키는 포인터를 담은 구조로 이루어져 있다.
- 연결 리스트는 Array처럼 선형 데이터 자료구조이지만, Array는 물리적인 배치 구조 자체가 연속적으로 저장되어 있고, Linked Array는 위 노드의 Next 부분에 다음 노드의 위치를 저장함으로써 선형적인 데이터 자료구조를 가진다.
- 리스트의 삽입과 삭제의 시간복잡도가 O(n)이 걸리는 것은 배열이 물리적인 데이터의 저장 위치가 연속적이어야 하므로 데이터를 옮기는 연산작업이 필요하기 때문이다.
- 하지만 연결 리스트는 데이터를 삽입, 삭제할 경우, 노드의 Next 부분에 저장한 다음 노드의 포인터만 변경해주면 되므로 배열과 비교했을 때 연결 리스트가 효율적으로 데이터를 삽입, 삭제할 수 있다.
- 하지만 특정 위치의 데이터를 탐색하기 위해서는 첫 노드부터 탐색을 시작해야한다.
- 그 시간이 O(n)만큼 걸리게 되므로 탐색에 있어서는 배열이나 트리 구조에 비해 상대적으로 느리다.
장점
- 연결 리스트의 길이를 동적으로 조절 가능하다.
- 데이터의 삽입과 삭제가 쉽다.
단점
- 임의의 노드에 바로 접근할 수 없다.
- 다음 노드의 위치를 저장하기 위한 추가 공간이 필요하다.
- Cache locality를 활용해 근접 데이터를 사전에 캐시에 저장하기 어렵다.
- 연결 리스트를 거꾸로 탐색하기 어렵다.
단일 연결 리스트
- 각 노드에 자료 공간에 한 개의 포인터 공간이 있고, 각 노드의 포인터는 다음 노드를 가리킨다.
삽입
삭제
파이썬 코드 구현
1 |
|
큐(Queue)
- 큐란 목록 한 쪽 끝에서만 자료를 넣고 다른 한쪽 끝에서만 자료를 빼낼 수 있는 자료구조이다.
- 먼저 집어넣은 데이터가 먼저 나오는(FIFO: Fist In, First Out, 선입선출)구조로 데이터를 저장한다.
- 데이터가 입력한 순서대로 처리되어야 할 경우에 사용한다.
- 큐에 새로운 데이터가 들어오면 큐의 끝에 데이터가 추가되며(enqueue), 반대로 삭제될 때는 첫번째 위치의 데이터가 삭제된다(dequeue).
종류
- 선형큐
- 문제점: 일반적인 선형 큐는 배열의 마지막 index를 가리키는 변수가 있고, dequeue가 일어날 때마다 비어 있는 공간이 생기면서 이를 활용할 수 없게 된다.
- 이 방식을 해결하기 위해 front를 고정시킨 채 뒤에 남아있는 데이터를 앞으로 한 칸 씩 땡길 수 밖에 없다.
- 이에 대한 대안으로 사용하는것이 원형큐이다.
- 환형큐
- 우선순위큐
파이썬 코드 구현
1 |
|
스택(Stack)
- 스택은 데이터의 삽입과 삭제가 저장소의 맨 윗 부분(the top of stack)에서만 일어나는 자료구조이다.
- 스택은 데이터가 순서대로 저장되고 스택의 마지막에 넣은 요소가 처음으로 꺼내진다(LIFO: Last In, First Out).
- 스택은 연속으로 저장된 데이터 구조를 가지고 있고 맨 위 요소에 대한 포인터(주소값)을 갖고 있는 Array나 singly linked list로 구현할 수 있다.
- 스택은 함수의 콜스택, 문자열을 역순으로 출력하거나 연산자 후위표기법 등에 사용된다.
장점
- 참조 지역성(한번 참조된 곳은 다시 참조될 확률이 높다)을 활용할 수 있다.
단점
- 데이터를 탐색하기 어렵다.
스택의 ADT
- push(None): 맨 위에 값 추가
- pop(data): 가장 최근에 넣은 맨 위의 값을 제거
- peak(data or -1): 스택의 변형 없이 맨 위에 값을 출력
- is_empty(bool): 스택이 비어있는지 확인
파이썬 코드 구현
1 |
|
덱(Deque)
- 큐가 선입선출 방식으로 작동한다면, 양방향 큐가 있는데 그것이 바로 덱이다.
- 앞, 뒤 양쪽에서 엘리먼트를 추가하거나 제거할 수 있다.
- 덱는 양 끝 엘리먼트의 append와 pop가 압도적으로 빠르다.
- 컨테이너의 양 끝 엘리먼트에 접근하여 삽입 또는 제거를 할 경우, 일반적인 리스트가 이러한 연산에 O(n)이 소요되는 데 반해, 덱은 O(1)로 접근이 가능하다.
언제? 왜?
- 덱은 스택처럼 사용할 수도 있고, 큐처럼 사용할 수도 있다.
- 시작점의 값을 넣고 빼거나, 끝 점의 값을 넣고 빼는 데 최적화된 연산 속도를 제공한다.
- 대부분의 경우 덱은 리스트보다 월등한 옵션이다.
- 덱은 특히 push/pop 연산이 빈번한 알고리즘에서 리스트보다 월등한 속도를 자랑한다.
파이썬 코드 구현
1 |
|