본문 바로가기

Data Structure & Algorithm

(31)
정렬(Sorting) 알고리즘 정렬 알고리즘 개요 정렬(Sorting)이란 데이터를 특정한 기준에 따라서 순서대로 나열한 것을 말한다. 프로그램에서 데이터를 가공할 때 오름차순이나 내림차순 등 대부분 어떤 식으로든 정렬해서 사용하는 경우가 많기에 정렬 알고리즘은 프로그램을 작성할 때 가장 많이 사용되는 알고리즘 중 하나다. 보통 정렬부터 공부하면 '알고리즘의 효율성'을 쉽게 이해할 수 있어 알고리즘 개론서 초반에 정렬 알고리즘을 설명하는 경우가 많다. 또한 일반적으로 문제에서 요구하는 조건에 따라서 적절한 정렬 알고리즘이 공식처럼 사용된다. 상황에 적절하지 못한 정렬 알고리즘을 이용하면 당연히 프로그램은 비효율적으로 동작하며 필요 이상으로 시간을 많이 소요한다. 그래서 정렬 알고리즘을 공부하다 보면 자연스럽게 알고리즘 효율의 중요성을..
복잡도(Complexity) 복잡도(Complexity)는 알고리즘의 성능을 나타내는 척도이다. 복잡도는 시간 복잡도(Time Complexity)와 공간 복잡도(Space Complexity)로 나눌 수 있다. 간단히 말해서, 시간 복잡도는 특정한 크기의 입력에 대하여 알고리즘이 얼마나 오래 걸리는지를 의미하고 공간 복잡도는 특정한 크기의 입력에 대하여 알고리즘이 얼마나 많은 메모리를 차지하는지를 의미한다. 동일한 기능을 수행하는 알고리즘이 있다면 일반적으로 복잡도가 낮을수록 좋은 알고리즘이다. 복잡도를 측정함으로써 다음의 2가지를 계산할 수 있다. 시간 복잡도: 알고리즘을 위해 필요한 연산의 횟수 공간 복잡도 : 알고리즘을 위해 필요한 메모리의 양 효율적인 알고리즘을 사용한다고 했을 때 보통 시간 복잡도와 공간 복잡도는 일종의 ..
탐색 알고리즘 DFS / BFS DFS DFS는 Depth-First Search, 깊이 우선 탐색이라고도 부르며, 그래프에서 깊은 부분을 우선적으로 탐색하는 알고리즘이다. DFS를 설명하기 전에 먼저 그래프(Graph)의 기본 구조를 알아야 한다. 그래프는 노드(Node)와 간선(Edge)으로 표현되며 이때 노드를 정점(Vertex)이라고도 말한다. 그래프 탐색이란 하나의 노드를 시작으로 다수의 노드를 방문하는 것을 말한다. 또한 두 노드가 간선으로 연결되어 있다면 '두 노드는 인접하다(Adjacent)'라고 표현한다. 여기에서 갑자기 노드와 간선이라는 생소한 단어가 나와서 헷갈릴 수도 있는데, 일반적으로 그래프를 표현할 때 사용하는 단어들이다. 노드를 도시, 간선을 도로라고 생각해보자. A라는 도시(노드)에서 B라는 도시(노드)로 ..
재귀 함수(Recursive Function) 재귀 함수(Recursive Function)란 자기 자신을 다시 호출하는 함수를 의미한다. DFS와 BFS를 구현하려면 재귀 함수도 이해하고 있어야 한다. 가장 간단한 재귀 함수는 다음과 같다. def recursive_function(): print('재귀 함수를 호출합니다.') recursive_function() recursive_function() 이 코드를 실행하면 '재귀 함수를 호출합니다.'라는 문자열을 무수히 출력한다. 여기서 정의한 recursive_function()이 자기 자신을 계속해서 추가로 불러오기 때문이다. 물론 어느 정도 출력하다가 다음과 같은 오류 메시지를 출력하고 멈출 것이다. RecursionError: maximum recursion depth exceeded whil..
스택(Stack)과 큐(Queue) - 자료구조 기초 탐색(Search)이란 많은 양의 데이터 중에서 원하는 데이터를 찾는 과정을 의미한다. 프로그래밍에서는 그래프, 트리 등의 자료구조 안에서 탐색을 하는 문제를 자주 다룬다. 대표적인 탐색 알고리즘으로 DFS와 BFS를 꼽을 수 있는데 이 두 알고리즘의 원리를 제대로 이해해야 코딩 테스트의 탐색 문제 유형을 풀 수 있다. 그런데 DFS와 BFS를 제대로 이해하려면 기본 자료구조인 스택과 큐에 대한 이해가 전제되어야 하므로 사전 학습으로 스택과 큐, 재귀 함수를 간단히 정리하고자 한다. 자료구조(Data Structure)란 '데이터를 표현하고 관리하고 처리하기 위한 구조'를 의미한다. 그 중 스택과 큐는 자료구조의 기초 개념으로 다음의 두 핵심적인 함수로 구성된다. 삽입(Push) : 데이터를 삽입한다. ..
구현(Implementation) 피지컬로 승부하기 코딩 테스트에서 구현(Implementation)이란 '머릿속에 있는 알고리즘을 소스코드로 바꾸는 과정'이다. 어떤 문제를 풀든 간에 소스코드를 작성하는 과정은 필수이므로 구현 문제 유형은 모든 범위의 코딩 테스트 문제 유형을 포함하는 개념이다. 우리는 알고리즘 문제를 해결할 때, 문제를 읽고 문제 풀이 방법을 고민한다. 고민 끝에 문제에 대한 정확한 풀이 방법이 떠오르면 바로 정답 처리를 받을 수 있을까? 그렇지 않다. 생각해낸 문제 풀이 방법을 우리가 원하는 프로그래밍 언어로 정확히 구현해냈을 때 비로소 정답 처리를 받을 수 있다. 이를 위해 프로그래밍 언어의 문법을 정확히 알고 있어야 하며 문제의 요구사항에 어긋나지 않는 답안 코드를 실수 없이 작성해야 한다. 흔히 문제 해결 분야..
그리디(Greedy) 알고리즘 그리디(Greedy) 알고리즘은 단순하지만 강력한 문제 해결 방법이다. 이 알고리즘 유형은 국내 알고리즘 교재에서 단어 그대로 번역하여 '탐욕법'으로 소개된다. 이름에서 알 수 있듯이 어떠한 문제가 있을 때 단순 무식하게, 탐욕적으로 푸는 알고리즘이다. 여기서 '탐욕적'이라는 말은 '현재 상황에서 지금 당장 좋은 것만 고르는 방법'을 의미한다. 그리디 알고리즘을 이용하면 매 순간 가장 좋아 보이는 것을 선택하며, 현재의 선택이 나중에 미칠 영향에 대해서는 고려하지 않는다. 코딩 테스트에서 만나게 될 그리디 알고리즘의 문제 유형은 앞으로 다루게 될 알고리즘과 비교했을 때 '사전에 외우고 있지 않아도 풀 수 있는 가능성이 높은 문제 유형'이라는 특징이 있다. 반면 이후에 공부할 정렬, 최단 경로 등의 알고리..