저자의 강의 경험을 바탕으로 알고리즘 이해에 있어 가장 기본적이고 공통된 부분을 발췌, 정리하였다. 주어진 문제가 어떤 특성을 가졌는지를 분석해보면 그 문제를 해결할 알고리즘을 고안하는 실마리를 찾을 수 있다. 이를 통해 알고리즘의 핵심 아이디어를 유추해보면, 알고리즘을 보다 쉽게 이해할 수 있다.
또한 예제를 통해 알고리즘의 수행과정을 상세히 step-by-step으로 보임으로써 알고리즘을 완전히 이해할 수 있도록 하였다. 아울러 시간복잡도를 분석하고, 알고리즘의 효용성을 위해 알고리즘이 실제로 활용되는 사례들을 설명하였다.
개정판에는 비교적 최신 정렬 알고리즘인 이중 피봇 퀵 정렬과 Tim Sort를 부록 V에 추가하였으며, 정렬 알고리즘들의 성능 비교를 표로 만들어 아울러 추가하였다. 이중 피봇 퀵 정렬은 퀵 정렬 대신에 최신 버전의 Java 언어의 원시 타입 정렬 라이브러리로 사용되고 있으며, Tim Sort는 일반적으로 성능이 다른 정렬 알고리즘보다 우수하여 파이선, 안드로이드, Java 언어의 객체 타입 정렬 라이브러리로 사용되고 있다.
컴퓨터를 전공하는 대부분의 학생들에게 알고리즘의 이해는 만만치 않은 어려움을 주는 것 같다. 필자의 경험에 비추어볼 때, 알고리즘의 어려움은 여러 다양한 경우들을 조목조목 ‘따져보는’ 논리적 검토 과정에서 비롯되는 것으로 보인다. 그러나 실제 알고리즘은 컴퓨터 분야뿐만 아니라 과학, 공학, 경영학 등 광범위한 분야에서 나타나는 많은 중요한 문제들을 해결하는 기본적인 방법들과 직간접적으로 관련되어 있어, 반드시 이해하고 숙달할 필요가 있다.
본서는 필자의 강의 경험을 바탕으로 알고리즘 이해에 있어 가장 기본적이고 공통된 부분을 발췌, 정리하였다. 독자들의 쉬운 이해를 위해 각 알고리즘에 대해 다음의 네 가지 단계를 염두에 두고 설명하였다.
1. 주어진 문제에 대한 이해와 분석
2. 알고리즘의 핵심 아이디어 유추
3. 알고리즘 소개 및 단계별 설명
4. 예제 따라 알고리즘 이해하기
주어진 문제가 어떤 특성을 가졌는지를 분석해보면 그 문제를 해결할 알고리즘을 고안하는 실마리를 찾을 수 있다. 이를 통해 알고리즘의 핵심 아이디어를 유추해보면, 알고리즘을 보다 쉽게 이해할 수 있다. 또한 예제를 통해 알고리즘의 수행과정을 상세히 step-by-step으로 보임으로써 알고리즘을 완전히 이해할 수 있도록 하였다. 아울러 시간복잡도를 분석하고, 알고리즘의 효용성을 위해 알고리즘이 실제로 활용되는 사례들을 설명하였다.
개정판의 개선 내용
이 책은 자료구조에 대한 기본 개념을 갖춘 학부 3, 4학년 학생들을 위하여 집필되었으나, 기술고시, 올림피아드와 같은 경시대회를 준비하는 학생들에게도 도움이 될 것이다. 또한 데이터 사이언스, 전자공학, 수학, 경영학을 전공하는 학생들에게는 알고리즘을 스스로 배우고 익힐 수 있는 좋은 입문서가 되리라 생각한다. 독자들이 알고리즘의 기본 개념을 이해함으로써 궁극적으로는 실세계의 어떤 문제가 주어지더라도 그 문제를 분석하고 해결할 수 있는 능력을 가질 수 있게 되기를 바라는 마음이다.
개정판에는 비교적 최신 정렬 알고리즘인 이중 피봇 퀵 정렬과 Tim Sort를 부록 V에 추가하였으며, 정렬 알고리즘들의 성능 비교를 표로 만들어 아울러 추가하였다. 이중 피봇 퀵 정렬은 퀵 정렬 대신에 최신 버전의 Java 언어의 원시 타입 정렬 라이브러리로 사용되고 있으며, Tim Sort는 일반적으로 성능이 다른 정렬 알고리즘보다 우수하여 파이선, 안드로이드, Java 언어의 객체 타입 정렬 라이브러리로 사용되고 있다.
또한 개정판에는 200개가 넘는 새 연습 문제가 추가되었다. 그중에 각 장의 연습 문제의 앞부분에는 기본 개념 파악을 위한 객관식 문제들과 입사 면접시험에 자주 등장하는 문제들로부터 난이도가 비교적 높은 주관식 문제들까지 추가되었다.
이 책의 내용
제1장 알고리즘의 첫걸음
이미 우리가 알고 있는 알고리즘들부터 수수께끼같이 재미있는 문제에 대한 알고리즘들을 살펴본다.
제2장 알고리즘을 배우기 위한 준비
알고리즘이란 무엇인가를 알아보고, 최초의 알고리즘인 유클리드의 최대공약수 알고리즘을 소개하며, 3장부터 다루는 알고리즘들을 배울 준비를 위한 알고리즘의 표현방법, 알고리즘의 분류, 알고리즘의 효율성 표현 방법, 복잡도의 점근적 표기를 소개하고, 마지막으로 왜 효율적인 알고리즘이 필요한가를 설명한다.
제3장 분할 정복 알고리즘
분할 정복(Divide-and-Conquer) 알고리즘으로 해결되는 문제들을 소개하고, 그에 대한 알고리즘들을 설명한다. 합병 정렬(Merge sort), 퀵 정렬(Quick sort), 선택(Selection) 문제, 최근접 점의 쌍(Closest Pair) 찾기 문제를 다룬다.
제4장 그리디 알고리즘
그리디(Greedy) 알고리즘은 top-down 방식으로 최적화 문제를 해결하는 알고리즘이다. 동전 거스름돈(Coin Change), 최소 신장 트리(Minimum Spanning Tree), 최단 경로(Shortest Path), 부분 배낭(Fractional Knapsack) 문제, 집합 커버(Set Cover), 작업 스케줄링(Task Scheduling), 허프만 압축(Huffman Encoding)에 대한 그리디 알고리즘을 각각 소개한다.
제5장 동적 계획 알고리즘
동적 계획(Dynamic Programming) 알고리즘은 최적화 문제를 해결하는 bottom-up 방식의 알고리즘이다. 모든 쌍 최단 경로(All Pairs Shortest Paths), 연속 행렬 곱셈(Chained Matrix Multiplication), 편집 거리(Edit Distance) 문제, 배낭(Knapsack) 문제, 동전 거스름돈(Coin Change) 문제의 동적 계획 알고리즘을 소개한다.
제6장 정렬 알고리즘
기본적인 정렬 알고리즘인 버블 정렬(Bubble sort), 선택 정렬(Selection sort), 삽입 정렬(Insertion sort)을 다루고, 이보다 효율적인 쉘 정렬(Shell sort)과 힙 정렬(Heap sort)을 살펴보며, 특정 환경에서 사용되는 기수 정렬(Radix sort)과 외부정렬(External sort)을 소개한다.
제7장 NP-완전 문제
앞장에서 소개된 대부분의 문제들은 다항식 시간복잡도의 알고리즘으로 해결되나, 실세계에서 많이 응용되는 중요한 문제들은 그러하지 못하다. 이러한 문제들 중에서 대표적인 NP-완전 문제들을 이해하고, 그 문제들 간의 관계를 살펴본다.
제8장 근사 알고리즘
지수 시간복잡도를 가진 NP-완전 문제들에 대한 정확한 해보다는 근사 해
(approximation solution)를 찾는 알고리즘들을 소개한다. 이를 위해 여행자 문제(Traveling Salesman Problem), 정점 커버(Vertex Cover) 문제, 통 채우기(Bin Packing) 문제, 작업 스케줄링(Job Scheduling) 문제, 클러스터링(Clustering) 문제의 근사 알고리즘을 각각 알아본다.
제9장 해 탐색 알고리즘
NP-완전 문제의 해를 탐색하기 위한 다양한 알고리즘을 소개한다. 백트래킹(Backtracking) 기법, 분기 한정(Branch-and-Bound) 기법, 유전자 알고리즘
(Genetic Algorithm), 모의 담금질(Simulated Annealing) 기법을 소개한다.