알고리즘이란?
알고리즘은 어떠한 문제를 해결하기 위한 일련의 절차를 공식화한 형태로 표한한 것이다. 예를 들어 일상 속에서는
다음과 같은 알고리즘을 찾을 수 있다.
- 집에서 학교로 가는 길 찾기
- 샌드위치 만드는 방법
- 매점에 가서 물건 구매
최단 거리 혹은 최단 시간 내에 학교에 가는 길을 찾는 것, 샌드위치를 만들기 위한 재료를 준비하고 조리 순서를 진행하는것, 매점에서 물건을 집고 계산하는 것까지 모두 알고리즘이라 할수 있다.
프로그래밍에서 알고리즘은 input 값을 통해 output 값을 얻기 위한 계산 과정을 의미한다. 이러한 문제를 해결할때,
정확하고 효율적으로 결과값을 얻기 위해서 알고리즘이 필요하다.
알고리즘의 조건
좋은 알고리즘을 만들기 위해서는 다음과 같은 조건을 충족하여야 한다.
- 입력 : 외부에서 제공되는 자료가 0개 이상 존재
- 출력 : 적어도 2개 이상의 서로 다른 결과를 내어야 한다. 즉 모든 입력에 하나의 출력이 나오면 안됨.
- 명확성 : 수행 과정은 명확하고 모호하지 않은 명령어로 구성되어야 한다.
- 유한성 : 유한 번의 명령어를 수행 후 유한 시간 내에 종료한다.
- 효율성 : 모든 과정은 명백하게 실행 가능(검증 가능)한 것이어야 한다.
공부 순서
사용할 언어와 그 언어에 대한 문법과 클래스를 어느정도 알고 있다는 가정하에 아래와 같은 순서로 공부.
- 기본 개념 이해
- 기본 알고리즘 코드 학습
- 쉬운 문제 풀기
- (어려운 개념 이해 & 문제 풀기)
알고리즘 공부 시작하기
1. 기본 개념 이해
* 알고리즘에 필요한 기본 개념
3줄 요약:
- 시간 복잡도
- 자료구조
- 정렬
시간 복잡도
문제를 해결하는데 걸리는 시간과 입력의 함수 관계 프로그램을 작성할 때에 입력의 크기에 따라서 프로그램이 계산하는 횟수가 크게 달라진다.
입력된 자료의 양과 알고리즘 실행에 걸리는 시간 사이에는 어느 정도의 관계가 있다. 이것을 알고리즘의 시간 복잡도라 한다.
cf. 메모리 공간을 얼마나 차지하느냐를 계산하는 공간 복잡도라는 개념도 있지만,
저장 기술의 발달로 인해 현재는 시간 복잡도를 우선 고려하는 경우가 많다.
시간 복잡도를 나타낼 떄에는 Big O표기법을 이요. 예를 들어, 1부터 n까지의 합을 구한다고 할떄 다음과 같은 두가지 방법이 있다.
// 방법 1
int n, res = 0;
for (int i = 1; i <= n;, i++) {
res += i;
}
System.out.println(res);// 방법 2
int n, res = 0;
res = n*(n+1)/2;
System.out.println(res);코드를 살펴보면 방법1에서는 for를 이용해 n번의 연산을 하기 때문에 o(n)의 시간 복잡도를 가진다. 반면 방법2에서는 n의 크기와 상관 없이 1번의 연산을 하기 때문에 o(1)의 시간 복잡도를 가진다.

맨 위에서 부터 시간 복잡도가 낮고 빠르고, 아래로 갈수록 시간 복잡도가 높고 느려진다. 제한된 시간 안에 올바르게 output을 출력하면 시간 복잡도를 낮춰야 할 것임을 알수 있다.
자료구조
자료구조란, 데이터 사이의 관계를 반영한 저장구조 및 그 조작 방법을 뜻한다. 컴퓨터의 프로그램을 실행하면 CPU에서 메모리로 데이터를 이동해서 처리하는데, 이 때 메모리를 효율적으로 사용하기 위해 데이터에 맞는 특성의 자료구조를 사용하는 것이 중요하다.
자료구조를 모두 나열하자면 아래 표와 같이 다양한 종류가 있다.

- 선형 자료구조 : 한 종류의 데이터가 선처럼 길게 나열된 자료구조.
- 비선형 자료구조 : 선형 자료구조가 아닌 모든 자료구조.i 번째 값을 탐색한 뒤의 i+1이 정해지지 않은 구조.
정렬
1. 버블정렬(Bubble sork)
버블정렬은 가장 쉬운 정렬 알고리즘이지만 시간복잡도가 좋은 퍼포먼스를 내지 못해서 실제로는 잘 사용되지 않는다.
시간복잡도는 O(n^2)이며 공간복잡도는 하나의 배열만 사용하여 정렬을 진행하기 때문에 O(n)이다.
***버블정렬 소스코드
버블정렬 파이썬 코드 찾아서 넣기
- 버블 정렬 -> 가장 쉽지만, 시간 복잡도가 높아 효율적이진 않다.
- 선택 정렬 -> 버블 정렬과 알고리즘이 유사하다. 가장 큰 수를 찾아 배열의 마지막 위치와 교환한다.
- 삽입 정렬 -> 인덱스를 설정하여 현재 위치의 값을 아래쪽으로 순회하며 알맞은 곳에 넣어준다.
- 병합 정렬 -> 정렬한 리스트를 반으로 쪼개며 좌우 리스트를 분할해 정렬 후 병합한다. 가장 많이 쓰이는 정렬중 하나.
- 힙 정렬 -> 힙이라는 자료구조를 통해 내림차순으로 숫자를 넣은 후, 역순으로 꺼내어 정렬한다.
- 퀵 정렬 -> pivot기준으로 좌측과 우측으로 작은 값과 긑 값을 재배치하고 분할하여 정렬한다.