출처 : visualgo.net
bubble_sort(A[1..N]) { # A[1..N]을 오름차순 정렬한다. for last <- N downto 2 for i <- 1 to last - 1 if (A[i] > A[i + 1]) then A[i] <-> A[i + 1] # 원소 교환 }
출처 : visualgo.net
insertion_sort(A[1..N]) { # A[1..N]을 오름차순 정렬한다. for i <- 2 to N { loc = i - 1; newItem = A[i]; # 이 지점에서 A[1..i-1]은 이미 정렬되어 있는 상태 while (1 <= loc and newItem < A[loc]) { A[loc + 1] <- A[loc]; loc--; } if (loc + 1 != i) then A[loc + 1] = newItem; }
출처 : visualgo.net
selection_sort(A[1..N]) { # A[1..N]을 오름차순 정렬한다. for first <- 1 to N - 1 { A[first..N]중 가장 작은 수 A[i]를 찾는다 if (first != i) then A[first] <-> A[i] # first i가 서로 다르면 A[first]와 A[i]를 교환 } }
출처 : visualgo.net
merge_sort(A[p..r]) { # A[p..r]을 오름차순 정렬한다. if (p < r) then { q <- ⌊(p + r) / 2⌋; # q는 p, r의 중간 지점 merge_sort(A, p, q); # 전반부 정렬 merge_sort(A, q + 1, r); # 후반부 정렬 merge(A, p, q, r); # 병합 } } #A[p..q]와 A[q+1..r]을 병합하여 A[p..r]을 오름차순 정렬된 상태로 만든다. #A[p..q]와 A[q+1..r]은 이미 오름차순으로 정렬되어 있다. merge(A[], p, q, r) { i <- p; j <- q + 1; t <- 1; while (i ≤ q and j ≤ r) { if (A[i] ≤ A[j]) then tmp[t++] <- A[i++]; # tmp[t] <- A[i]; t++; i++; else tmp[t++] <- A[j++]; # tmp[t] <- A[j]; t++; j++; } while (i ≤ q) # 왼쪽 배열 부분이 남은 경우 tmp[t++] <- A[i++]; while (j ≤ r) # 오른쪽 배열 부분이 남은 경우 tmp[t++] <- A[j++]; i <- p; t <- 1; while (i ≤ r) # 결과를 A[p..r]에 저장 A[i++] <- tmp[t++];
heap_sort(A[1..n]) { # A[1..n]을 정렬한다. build_min_heap(A, n); for i <- n downto 2 { A[1] <-> A[i]; # 원소 교환 heapify(A, 1, i - 1); } } build_min_heap(A[], n) { for i <- ⌊n / 2⌋ downto 1 heapify(A, i, n) } #A[k]를 루트로 하는 트리를 최소 힙 성질을 만족하도록 수정한다. #A[k]의 두 자식을 루트로 하는 서브 트리는 최소 힙 성질을 만족하고 있다. #n은 배열 A의 전체 크기이며 최대 인덱스를 나타낸다. heapify(A[], k, n) { left <- 2k; right <- 2k + 1; if (right ≤ n) then { if (A[left] < A[right]) then smaller <- left; else smaller <- right; } else if (left ≤ n) then smaller <- left; else return; # 최소 힙 성질을 만족하지 못하는 경우 재귀적으로 수정한다. if (A[smaller] < A[k]) then { A[k] <-> A[smaller]; heapify(A, smaller, n); } }
출처 : visualgo.net
quick_sort(A[p..r]) { # A[p..r]을 오름차순 정렬한다. if (p < r) then { q <- partition(A, p, r); # 분할 quick_sort(A, p, q - 1); # 왼쪽 부분 배열 정렬 quick_sort(A, q + 1, r); # 오른쪽 부분 배열 정렬 } } partition(A[], p, r) { x <- A[r]; # 기준원소 i <- p - 1; # i는 x보다 작거나 작은 원소들의 끝지점 for j <- p to r - 1 # j는 아직 정해지지 않은 원소들의 시작 지점 if (A[j] ≤ x) then A[++i] <-> A[j]; # i값 증가 후 A[i] <-> A[j] 교환 if (i + 1 != r) then A[i + 1] <-> A[r]; # i + 1과 r이 서로 다르면 A[i + 1]과 A[r]을 교환 return i + 1; }
위 그림은 각 영역의 첫번째 원소가 pivot
의사코드는 각 영역의 마지막 원소가 pivot
counting_sort(A[p..r]) { # A[p..r]을 오름차순 정렬한다. for i <- p to r C[A[i]]++; for i <- 2 to k # 누적 합 C[i] += C[i-1] for i <- r to p{ # 들어갈 위치 지정 B[C[A[i]]-1] = A[i] C[A[i]]--; } }
#include <iostream> #include <string> #include <vector> using namespace std; string solution(string s) { vector<int> count (26, 0); string answer(s.size(), '0'); for (auto& c : s) { count[c-'a']++; } for (int i=1; i<count.size(); i++) { count[i] += count[i-1]; } for (auto it = s.rbegin(); it != s.rend(); ++it) { int index = count[*it - 'a'] - 1; answer[index] = *it; count[*it - 'a'] --; } return answer; } int main() { cout << solution("hello") << endl; // 출력값 : ehllo cout << solution("algorithm") << endl; // 출력값 : aghilmort return 0; }
topological_sort(G): for 각 정점 v: in_degree[v] ← 0 for 각 간선 (u → v): in_degree[v] ← in_degree[v] + 1 Q ← 진입 차수가 0인 모든 정점을 큐에 삽입 while Q가 비어있지 않다면: v ← Q에서 꺼냄 v를 결과 리스트에 추가 for v의 모든 인접 정점 w: in_degree[w] ← in_degree[w] - 1 if in_degree[w] = 0: Q에 w를 추가 if 결과 리스트에 모든 정점이 없다면: "사이클 존재" else: 결과 리스트 출력