본문 바로가기

부스트코스

(40)
자료 구조 | 스택, 큐, 딕셔너리 간단하지만 많이 쓰이는 데이터 구조 세 가지를 살펴보자. 학습 목표 스택, 큐, 딕셔너리의 원리와 구조를 설명할 수 있다. 큐 큐(Queue)는 값이 아래로 쌓이는 구조다. 값을 넣고 뺄 때 선입 선출(FIFO, First in first out) 방식을 따른다. 배열이나 연결 리스트를 통해 구현할 수 있다. 스택 스택(Stack)은 값이 위로 쌓이는 구조다. 값을 넣고 뺄 때 후입 선출(LIFO, last in first out) 방식을 따른다. 배열이나 연결 리스트를 통해 구현할 수 있다. 딕셔너리 딕셔너리(Dictionary)는 키(Key)와 값(Value)이라는 요소로 이루어져 있다(쌍으로 이루어짐). 키에 해당하는 값을 저장하고 읽어오는 방식이다. 일반적으로 해시 테이블과 동일한 개념이라 할 수..
자료 구조 | 트라이 학습 목표 트라이의 원리와 구조를 설명할 수 있다. 트라이 트라이(trie)는 기본적으로 트리 형태의 자료 구조다. 트라이는 각 노드가 배열로 이루어져 있다는게 특징이다. 예시를 보자. 영어 알파벳으로 이루어진 문자열 값을 저장한다고 생각해보자. 노드는 a부터 z까지의 값을 가지는 배열이 될 것이다. 배열의 각 요소, 즉 알파벳은 다음 층의 노드(a-z배열)를 가리킨다. 트라이의 시간 복잡도 앞선 예시와 같은 트라이에서 값을 검색하는데 걸리는 시간은 문자열의 길이에 의해 정해진다. 일반적인 영어 이름의 길이를 n이라고 했을 때, 검색 시간은 O(n)이지만, 대부분의 이름은 그리 크지 않은 상수이기 때문에 O(1)이나 마찬가지다. 생각해보기 트라이가 해시 테이블에 비해 가지는 장점과 단점은 무엇일까. 트라..
자료 구조 | 해시 테이블 연결 리스트나 트리에서 값을 검색할 땐 O(n) 또는 O(log n)의 시간이 걸린다. 이 시간을 단축해서 거의 O(1)에 가깝게 할 수 있을까? 학습 목표 해시 테이블의 원리와 구조를 설명할 수 있다. 해시 테이블 해시 테이블(hash table)은 자료 구조 중 하나로 연결 리스트의 배열을 사용해 데이터를 저장한다. 각각의 데이터는 해시 함수를 통해 고유한 인덱스를 생성하고, 이를 활용해 값을 저장하거나 검색하게 된다. 실제 값이 저장되는 장소를 버킷 또는 슬롯이라고 한다. 쉬운 예시를 보자. 예시에서는 사람의 이름이 해시 테이블에 저장되며, 해시 함수는 '이름의 가정 첫 글자'이다. 이 경우 알파벳 개수에 해당하는 총 26개의 포인터들이 있을 수 있으며, 각 포인터는 그 알파벳을 시작으로 하는 이름..
자료 구조 | 연결리스트(3) 트리 연결 리스트에서는 각 요소가 다른 요소를 하나씩만 가리키고 있었다. 만약 가리키는 요소가 여러 개가 된다면 어떻게 될까. 학습 목표 트리의 구조를 설명하고 활용하는 코드를 작성할 수 있다. 연결 리스트와 트리 트리는 연결 리스트를 기반으로 한 데이터 구조다. 연결 리스트에서 각 노드들의 연결이 1차원적이었다면, 트리에서는 2차원적으로 구성되어 있다. 각 노드는 일정한 층에 속하고 다음 층의 노드를 가리키는 포인터를 가진다. 트리가 시작되는 노드를 루트라고 한다. 루트는 다음 층의 노드를 가리키며 이를 자식 노드라고 한다. 이진 검색 트리에서 하나의 노드는 두 개의 자식 노드를 가진다. 왼쪽 자식 노드는 자신의 값보다 작고, 오른쪽 자식 노드는 크다. 이러한 트리 구조는 이진 검색을 수행하는데 유리하다. ..
자료 구조 | 연결 리스트(2) 코딩 및 특징 학습 목표 연결 리스트를 구현하고 사용할 수 있다. 연결 리스트와 배열의 장단점을 설명할 수 있다. 연결 리스트 코딩 구조체를 이용하여 실제 연결 리스트를 구현해보자. 지난 포스팅에서 본 그림을 생각하며 코드를 살펴보자. #include #include typedef struct node{ int number; struct node *next; } node; int main(void) { // list라는 이름의 node 포인터 정의 // 아무 것도 가리키고 있지 않기 때문에 NULL로 초기화 node *list = NULL; // 새로운 node를 위해 포인터를 정의하고 메모리 할당 node *n = malloc(sizeof(node)); if(n == NULL){ return 1; } // n의 nu..
자료 구조 | 연결 리스트(1) 도입 이제껏 여러 자료형의 데이터를 메모리 상에 저장하고 삭제하는 방법을 배웠다. 이번 강의부터는 메모리를 좀 더 효율적으로 관리하고 사용하는 법을 배운다. 데이터 구조의 개념과 연결 리스트에 대해 알아보자. 학습 목표 연결 리스트의 정의를 설명할 수 있다. 데이터 구조와 연결 리스트 데이터 구조는 메모리를 좀 더 효율적으로 관리하기 위해 새로 정의하는 구조체다. 연결 리스트(linked list)는 데이터 구조 중 하나이다. 배열에서는 각 인덱스의 값이 메모리 상에 연이어 저장되었다. 하지만 메모리 상의 어디에 있든 주소만 알고 있다면 연이어 값을 읽을 수 있다. 이러한 개념을 사용한 것이 연결 리스트이다. 연결 리스트는 각 인덱스의 메모리 주소에서 자신의 값과 다음 값의 주소(포인터)를 저장한다. 연결 리..
C 언어 | 배열의 크기 조정하기 학습 목표 배열의 크기를 조정하는 코드를 작성할 수 있다. 컴퓨터 안의 메모리는 마치 사물함과 같다. 한 번 사물함의 개수를 정한 이후에는 공간이 모자란다고 해서 주변의 사물함을 마음대로 더 사용할 수 없다. 배열을 정의할 때도 마찬가지다. 이미 일정한 크기가 할당되어 있는 상황에서 그 크기를 늘리는 일은 단순하지 않다. 배열의 크기 조정하기 1. for 루프를 사용해 값 복사 배열의 크기를 키워야 한다면 어떻게 해야 할까. 배열이 저장된 메모리 위치 옆에 메모리를 덧붙이자 생각할 수 있지만, 그곳에는 다른 데이터가 저장돼 있을 수 있다. 따라서 안전하게 배열의 크기를 키우기 위해서는 새로운 공간에 큰 크기의 메모리를 다시 할당하고 배열의 값을 하나씩 옮겨줘야 한다. 이 과정은 배열의 크기(n)만큼 시간..
C 언어 | malloc과 포인터 학습 목표 포인터의 개념과 malloc 함수의 용법을 잘 이해할 수 있다. 6주 차부터는 C로 구현할 수 있는 다양한 데이터 구조를 배운다. 데이터 구조를 정의하고 관리하기에 앞서 메모리와 포인터에 대한 개념을 정확히 이해해야 한다. malloc과 포인터 지난 포스팅의 malloc 함수와 포인터를 복습하는 예제를 보자. 코드를 살펴보자. main 함수에서 먼저 포인터 x와 y를 선언한다. x에 malloc 함수를 이용해 int 자료형에 해당하는 메모리를 할당한다. x와 y 포인터가 가리키는 지점에 각각 정수를 저장한다. 코드에는 한 가지 오류가 있다. 프로그램을 실행시켜보자. 에러를 보면 포인터 y에 문제가 있음을 알 수 있다. y는 포인터로 선언되었을 뿐이지 x처럼 메모리를 할당받지 못했다. 어디를 가..