자료구조
자료구조는 다수의 데이터를 담기 위한 구조이다.
성능 비교 : 자료구조/알고리즘의 성능 측정 방법에 대해 이해할 필요가 있음
1. 선형 구조
- 선형 자료구조는 하나의 데이터 뒤에 다른 데이터가 하나 존재하는 자료구조다.
- 데이터가 일렬로 연속적으로 연결되어 있다.
2. 비선형 구조
- 하나의 데이터 뒤에 다른 데이터가 여러 개 올 수 있는 자료구조다.
- 데이터가 일직선상으로 연결되어 있지 않아도 된다. (트리, 그래프)
시간복잡도
공간 복잡도
복잡도를 표현할 대는 Big-O 표기법을 사용한다.
- 특정한 알고리즘이 얼마나 효율적인지 수치적으로 표현할 수 있다.
- 가장 빠르게 증가하는 항만을 고려하는 표기법이다.
이중 for문 같은 경우는 O(n^2)
- 일반적으로 연산 횟수가 10억을 넘어가면 1초 이상의 시간이 소요된다.
배열
- 가장 기본적인 자료구조
- 여러 개의 변수를 담는 공간으로 이해할 수 있다.
- 배열은 인덱스가 존재하며, 인덱스는 0부터 시작한다.
- 특정한 인덱스에 직접적으로 접근 가능 -> 수행 시간 : O(1)
- 컴퓨터의 메인 메모리에서 배열의 공간은 연속적으로 할당된다.
- 장점 : 캐시 히트 가능성이 높으며, 조회가 빠르다.
- 단점 : 배열의 크기를 미리 지정해야 하는 것이 일반적이므로, 데이터의 추가 및 삭제에 한계가 있다.
연결 리스트
- 연결 리스트는 컴퓨터의 메인 메모리상에서 주소가 연속적이지 않다.
- 배열과 다르게 크기가 정해져 있지 않고, 리스트의 크기는 동적으로 변경 가능하다.
2차원 배열 만들기
let arr = Array.from(Array(4), ()=> new Array(5))
자바스크립트의 배열은 연결리스트 구조의 배열이다
- 자료의 위치를 가지고 있는 포인터를 가지고 있다.
스택
- 먼저 들어온 데이터가 나중에 나가는 자료구조
- 흔히 박스가 쌓인 형태를 스택이라고 한다.
- 우리가 박스를 쌓은 뒤에 꺼낼 때는, 가장 마지막에 올렸던 박스부터 꺼내야 한다.
스택이 가지고 있는 연산
- 삽입 push : 스택에 원소를 삽입하는 연산
- 추출 pop : 스택에서 원소를 추출하는 연산
- 최상위 원소 top : 스택의 최상위 원소를 확인하는 연산
- Empty : 스택이 비어 있는지 확인하는 연산
자바스크립트는 기본적으로 push, pop 제공
일반적으로 스택을 구현할때 자바스크립트의 배열을 자료형을 사용한다.
let stack = []
stack.push(5)
stack.push(2)
stack.push(7)
stack.pop()
stack.push(5)
stack.pop()
- reverse를 사용하면 최상단 원소부터 확일 할 수 있음.
큐
- 먼저 삽입된 데이터가 먼저 추출되는 자료구조다.
- 게임 큐와 같이 먼저 대기한 사람이 먼저 게임에 매칭된다.
- 큐를 연결리스트로 구현하면, 삽입과 삭제에 있어서 O(1)을 보장할 수 있다.
- 연결 리스트로 구현할 때 머리와 꼬리 두 개의 포인터를 가진다.
- 머리 : 남아있는 원소 중 가장 먼저 들어 온 데이터를 가리키는 포인터
- 꼬리 : 남아있는 원소 중 가장 마지막에 들어 온 데이터를 가리키는 포인터
- 자바스크립트에서는 Dictionary 자료형을 이용하여 큐를 구현하면 간단하다.
일반 배열로 구현하면 비효율적.
class Queue {
constructor() {
this.items = {};
this.headIndex = 0;
this.tailIndex = 0;
}
enqueue(item) {
this.items[this.tailIndex] = item;
this.tailIndex++;
}
dequeue() {
const item = this.items[this.headIndex];
delete this.items[this.headIndex];
this.headIndex++;
return item;
}
peek() {
return this.items[this.headIndex];
}
getLength() {
return (this.tailIndex = this.headIndex);
}
}
const 큐 = {
0: 5,
1: 2,
2: 3,
3: 7,
//0
//4
};
const deq = {
// 0:5
0: 2,
1: 3,
2: 7,
//1
//4
};
const enq = {
0: 2,
1: 3,
2: 7,
5: 1,
//1
//5
};
const enq2 = {
0: 2,
1: 3,
2: 7,
5: 1,
6: 4,
// 1
// 6
};
const deq2 = {
//0: 2,
1: 3,
2: 7,
5: 1,
6: 4,
// 2
// 6
// getLength = 4 (tail - head)
};
트리
- 트리는 가계도와 같이 계층적인 구조를 표현할 때 사용할 수 있는 자료구조다.
- 나무의 형태를 뒤집은 것과 같이 생겼다.
용어
- 루트 : 부모가 없는 최상의 노드
- 단말노드(리프) : 자식이 없는 노드
- 깊이 : 루트 노드에서의 길이, 길이란 출발 에서 목적지까지 거쳐야 하는 간선의 수를 의미한다.
- 높이 : 루트 노드에서 가장 깊은 노드까지의 길이를 의미한다.
이진 트리
- 이진 트리는 최대 2개의 자식을 가질 수 있는 트리를 말한다.
우선순위 큐
- 우선순위 큐는 우선순위에 따라서 데이터를 추출하는 자료구조다.
- 컴퓨터 운영체제, 온라인 게임 매칭 등에서 활용된다.
- 우선순위 큐는 일반적으로 힙을 이용해 구현한다.
- 가장 운선위가 높은 데이터 (스케줄링 알고리즘)
구현 방법
- 데이터가 N개일 때, 구현 방식에 따른 시간 복잡도
리스트 자료형 삽입,삭제
힙 삽입,삭제
포화 이진 트리
완전 이진 트리
높이 균형트리
힙
- 힙은 원소들 중에서 최댓값 혹은 최솟값을 빠르게 찾아내는 자료구조다.
- 최대 힙 : 값이 큰 원소부터 추출한다.
- 최소 힙 : 값이 작은 원소부터 추출한다.
- 힙은 원소의 삽입과 삭제를 위해 O(logN)의 수행 시간을 요구한다.
- 단순한 N개의 데이터를 힙에 넣었다가 모두 꺼내는 작업은 정렬과 동일하다.
- 이 경우 시간 복잡도는 O(NlogN)이다
그래프
- 사물을 정점과 간선으로 나타내기 위한 도구다.
- 그래프는 두 가지 방식으로 구현할 수 있다.
- 인접 행렬 : 2차원 배열을 사용하는 방식
- 인접 리스트 : 연결 리스트를 이용하는 방식
인접 행렬
인접 리스트
- n * n 메모리가 필요하지 않기 때문에 메모리 효율적이다.
그래프의 시간 복잡도
- 인접 행렬 : 모든 정점들의 연결 여부를 저장해 O(v^2)의 공간을 요구한다.
- 공간 효율성이 떨어지지만, 두 노드의 연결 여부를 O(1)에 확인할 수 있다.
- 인접 리스트 : 연결된 간선의 정보만을 저장하여 O(V + E)의 공간을 요구한다.
- 공간 효율성이 우수하지만, 두 노드의 연결 여부를 확인하기 위해 O(V)의 시간이 필요하다.
인정 행렬 VS 인접 리스트
- 최단 경로 알고리즘을 구현할 때, 어떤 자료구조가 유용할까?
- 각각 근처의 노드와 연결되어 있는 경우가 많으므로, 간선 개수가 적어 인접 리스트가 유리하다.