C++ 코딩테스트 강좌, 소수 구하기

알고리즘은 컴퓨터 사이언스의 핵심 개념 중 하나로, 특히 프로그래밍 문제 해결에 있어 매우 중요합니다.
이번 강좌에서는 ‘소수를 구하는’ 문제를 다루고, 이를 해결하기 위한 알고리즘과 C++ 코드를 상세히 설명하겠습니다.
소수는 1과 자기 자신만으로 나누어 떨어지는 자연수를 의미하며, 기본적인 수학 개념 중 하나입니다.
하지만 이 문제를 해결하는 데 있어 다양한 접근 방법이 있으며, 각기 다른 시간 복잡도를 가질 수 있습니다.

문제 설명

주어진 정수 N이 있을 때, 1부터 N까지의 모든 소수를 구하는 프로그램을 작성하시오.
소수는 1보다 큰 자연수 중에서 1과 자기 자신 외에는 약수가 없는 수입니다.

입력

첫째 줄에 자연수 N (1 ≤ N ≤ 10^6)이 주어진다.

출력

1부터 N까지의 모든 소수를 한 줄에 하나씩 출력한다.

예제

입력:
    10

    출력:
    2
    3
    5
    7
    

알고리즘 접근 방법

소수를 구하는 여러 방법이 있지만, 여기서는 ‘에라토스테네스의 체’라는 고전적인 방법을 사용해 볼 것입니다.
이 방법은 효율적이고 비교적 간단하게 소수를 찾을 수 있습니다.
에라토스테네스의 체는 다음과 같은 절차로 동작합니다.

  1. 1부터 N까지의 모든 숫자를 나열합니다.
  2. 2부터 시작하여, 그 수의 배수를 모두 지웁니다.
  3. 다음 남은 수에 대해 위의 과정을 반복합니다.
  4. 남은 수를 소수로 간주하고 출력합니다.

시간 복잡도

에라토스테네스의 체 알고리즘은 약 O(N log log N)의 시간 복잡도를 가집니다.
이는 N이 커질수록 효율적이며, N = 10^6인 경우에도 빠른 속도를 보장합니다.

C++ 코드

아래는 위의 알고리즘을 C++로 구현한 코드입니다.
각 단계에 주석을 달아 이해를 돕도록 하겠습니다.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int N;
    cin >> N; // 사용자로부터 입력을 받습니다.

    // N+1 크기의 벡터를 생성하고, 모든 값을 true로 초기화합니다.
    vector<bool> isPrime(N + 1, true);
    isPrime[0] = isPrime[1] = false; // 0과 1은 소수가 아닙니다.

    // 2부터 N의 제곱근까지 반복합니다.
    for (int i = 2; i * i <= N; i++) {
        if (isPrime[i]) { // i가 소수라면,
            for (int j = i * i; j <= N; j += i) {
                isPrime[j] = false; // i의 배수는 소수가 아닙니다.
            }
        }
    }

    // 결과를 출력합니다.
    for (int i = 2; i <= N; i++) {
        if (isPrime[i]) {
            cout << i << "\n"; // 소수인 경우 출력합니다.
        }
    }

    return 0;
}
    

코드 설명

#include <iostream>#include <vector>:
C++의 입출력 및 벡터 라이브러리를 포함합니다.
int N;: 사용자 입력을 받을 정수 변수를 선언합니다.
vector<bool> isPrime(N + 1, true);:
N까지의 숫자에 대해 소수 여부를 저장할 벡터를 선언하며,
초기값은 모두 true로 설정합니다.
(0과 1은 소수가 아니므로 별도로 설정)
for (int i = 2; i * i <= N; i++):
2부터 시작해 N의 제곱근까지 반복하며 소수를 찾습니다.
– 내부의 for (int j = i * i; j <= N; j += i) 루프는
i의 배수를 지우는 역할을 합니다.
– 마지막으로 isPrime[i]true인 모든 인덱스를 출력합니다.

결론

이번 강좌에서는 소수를 구하는 문제를 해결하기 위한 알고리즘을 소개하고
C++ 코드를 구현해보았습니다. 에라토스테네스의 체 알고리즘은 효율적으로 소수를 찾을 수 있는 방법이며,
코딩 테스트에서도 자주 출제되는 문제입니다.
알고리즘과 코드를 숙지하여 자신감 있게 코딩 테스트에 도전해 보시기 바랍니다!

C++ 코딩테스트 강좌, 세일즈맨의 고민

세일즈맨의 고민은 전통적인 알고리즘 문제 중 하나로, “외판원 순회 문제” 또는 “여행하는 세일즈맨 문제”라고도 불린다.
이 문제는 여러 도시가 있을 때, 세일즈맨이 모든 도시를 방문한 후 다시 출발 도시로 돌아오는 가장 짧은 경로를 찾는 것이다.
이 문제는 조합 최적화(combinatorial optimization) 문제에 속하며 NP-hard로 분류된다.
따라서, 작은 데이터 셋은 브루트 포스(brute force) 알고리즘으로 해결할 수 있지만, 큰 데이터 셋은 더 효율적인 접근 방법이 필요하다.

문제 설명

N개의 도시가 주어지고, 각 도시 간의 거리 행렬이 주어진다. 목표는 세일즈맨이 각 도시에 한 번씩 방문한 후 출발 지점으로 돌아오는 가장 짧은 경로의 거리 합을 구하는 것이다.
다음은 문제의 형식이다.

        
        입력:
        N (도시의 수)
        거리 행렬 (nxn 행렬)
        
        출력:
        최소 경로의 길이
        
    

예제

입력 예시:

        4
        0 10 15 20
        10 0 35 25
        15 35 0 30
        20 25 30 0
    

출력 예시:
80

문제 해결 과정

문제를 해결하기 위한 여러 가지 접근법이 있으며, 여기서는 브루트 포스 알고리즘과 동적 프로그래밍(DP) 두 가지 방법을 사용하여 이 문제를 해결해보겠다.

1. 브루트 포스 방법

브루트 포스 방법은 모든 가능한 경로를 탐색하여 최단 경로를 찾는 방식이다.
모든 도시의 순열을 생성하여 각 경로 거리를 계산하고, 이 중에서 최소 거리를 찾는다.

알고리즘 설명

  1. 모든 도시의 순열을 생성한다.
  2. 각 순열에 대해 전체 거리 값을 계산한다.
  3. 계산된 거리 중 최소 거리 값을 찾는다.

C++ 코드 예시

        
        #include 
        #include 
        #include 
        #include 

        using namespace std;

        int calculateDistance(const vector>& dist, const vector& path) {
            int totalDistance = 0;
            for (int i = 0; i < path.size() - 1; i++) {
                totalDistance += dist[path[i]][path[i + 1]];
            }
            totalDistance += dist[path.back()][path[0]]; // Return to start
            return totalDistance;
        }

        int main() {
            int N;
            cin >> N;
            vector> dist(N, vector(N, 0));

            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++)
                    cin >> dist[i][j];

            vector cities(N);
            for (int i = 0; i < N; i++) cities[i] = i;

            int minDistance = INT_MAX;

            do {
                int currentDistance = calculateDistance(dist, cities);
                minDistance = min(minDistance, currentDistance);
            } while (next_permutation(cities.begin() + 1, cities.end())); // Fix first city

            cout << minDistance << endl;

            return 0;
        }
        
    

2. 동적 프로그래밍(DP) 방법

동적 프로그래밍 방법은 메모리를 효율적으로 사용하는 방법이다.
도시를 비트마스크로 표현하여 각 도시의 방문 여부를 나타내고, 재귀 함수와 메모이제이션을 이용하여 최단 경로를 계산한다.
이 경우 복잡도는 O(n^2 * 2^n)로 줄어든다. 다음은 동적 프로그래밍 솔루션의 설명이다.

알고리즘 설명

  1. 비트마스크를 사용하여 각 도시의 방문 여부를 나타낸다.
  2. 최소 비용 테이블을 초기화하고 0으로 설정한다.
  3. 재귀 함수를 통해 가능한 경로를 탐색하며 최소 거리 값을 갱신한다.

C++ 코드 예시

        
        #include 
        #include 
        #include 

        using namespace std;

        int tsp(int pos, int visited, const vector>& dist, vector>& memo) {
            if (visited == ((1 << dist.size()) - 1)) {
                return dist[pos][0]; // Return to the start city
            }

            if (memo[pos][visited] != -1) {
                return memo[pos][visited];
            }

            int minCost = INT_MAX;

            for (int city = 0; city < dist.size(); city++) {
                if ((visited & (1 << city)) == 0) {
                    int newCost = dist[pos][city] + tsp(city, visited | (1 << city), dist, memo);
                    minCost = min(minCost, newCost);
                }
            }

            return memo[pos][visited] = minCost;
        }

        int main() {
            int N;
            cin >> N;
            vector> dist(N, vector(N, 0));

            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++)
                    cin >> dist[i][j];

            vector> memo(N, vector((1 << N), -1));

            cout << tsp(0, 1, dist, memo) << endl;

            return 0;
        }
        
    

결론

이 강좌에서는 C++로 구현된 세일즈맨의 고민 문제를 통해 문제 정의, 예제,
그리고 문제 해결을 위한 브루트 포스 및 동적 프로그래밍 방법을 상세히 알아보았다.
주의할 점은 브루트 포스 방법은 도시의 수가 작을 때만 사용해야 하며, 도시의 수가 증가할수록 동적 프로그래밍 방법을 사용하는 것이 더 효율적이다.
이러한 알고리즘 문제들은 실제 코딩 테스트 및 면접에서 자주 등장하므로, 충분한 연습이 필요하다.

C++ 코딩테스트 강좌, 소수 & 팰린드롬 수 중에서 최솟값 찾기

오늘은 취업 준비생들에게 자주 출제되는 알고리즘 문제 중 하나인 ‘소수 및 팰린드롬 수 중에서 최솟값 찾기’에 대해 깊게 알아보겠습니다. 이 문제를 통해 우리는 소수와 팰린드롬의 개념을 복습하고, C++을 통해 알고리즘을 구현해보는 시간을 가지겠습니다.

문제 설명

주어진 정수 N이 있습니다. 이때 N보다 크거나 같고, N보다 작거나 같은 범위 내에서 소수이면서 팰린드롬인 정수 중에서 최솟값을 찾는 문제입니다.

예시

  • N = 10 일 경우, 소수 및 팰린드롬 수는 11 입니다.
  • N = 30 일 경우, 소수 및 팰린드롬 수는 31 입니다.
  • N = 100 일 경우, 소수 및 팰린드롬 수는 101 입니다.

문제 접근 방법

소수는 1보다 큰 정수 중 1과 자기 자신 이외의 약수를 가지지 않는 자연수입니다. 팰린드롬 수는 앞뒤에서 읽어도 동일한 수를 의미합니다. 예를 들어, 121, 12321 등이 있습니다.

문제를 해결하기 위해 다음의 단계를 따를 것입니다:

  1. N부터 시작하여 모든 수를 검사합니다.
  2. 각 숫자에 대해 소수인지 확인합니다.
  3. 소수인지 확인 후, 팰린드롬인지 확인합니다.
  4. 모든 조건을 만족하는 최솟값을 찾아 반환합니다.

C++ 구현

이제 C++ 언어를 사용하여 이 문제를 해결하는 코드를 작성해보겠습니다.

코드 설명


#include 
#include 
#include 

using namespace std;

// 소수 판별 함수
bool isPrime(int num) {
    if (num < 2) return false;
    for (int i = 2; i <= sqrt(num); ++i) {
        if (num % i == 0) return false;
    }
    return true;
}

// 팰린드롬 판별 함수
bool isPalindrome(int num) {
    string str = to_string(num);
    int len = str.length();
    for (int i = 0; i < len / 2; ++i) {
        if (str[i] != str[len - i - 1]) return false;
    }
    return true;
}

// N보다 크거나 같은 소수 및 팰린드롬의 최솟값을 찾는 함수
int findMinPrimePalindrome(int N) {
    for (int i = N; ; ++i) {
        if (isPrime(i) && isPalindrome(i)) {
            return i;
        }
    }
}

int main() {
    int N;
    cout << "정수 N을 입력하세요: ";
    cin >> N;
    
    int result = findMinPrimePalindrome(N);
    cout << "최솟값: " << result << endl;
    
    return 0;
}

    

코드 설명

위 코드를 통해 다음과 같은 과정을 거쳐 원하는 결과를 얻을 수 있습니다:

  1. isPrime 함수: 주어진 정수가 소수인지 판별합니다. 2 이상인 숫자만 판별하고, 2부터 sqrt(num)까지 나누어 떨어지는 숫자가 있는지 확인합니다.
  2. isPalindrome 함수: 주어진 정수가 팰린드롬인지 판별합니다. 숫자를 문자열로 변환 후, 앞에서부터와 뒤에서부터 비교하여 일치하는지 확인합니다.
  3. findMinPrimePalindrome 함수: 주어진 N부터 시작하여 모든 숫자에 대해 소수 및 팰린드롬 여부를 확인합니다. 소수이자 팰린드롬인 숫자를 발견하면 바로 반환합니다.
  4. main 함수: 사용자로부터 정수 N을 입력받고, 이를 기반으로 최솟값을 찾아 출력합니다.

이해를 돕기 위한 예제

예를 들어 N=10인 경우, 함수는 10부터 시작하여 10, 11을 확인합니다. 11은 소수이며 팰린드롬이므로 최솟값으로 11을 반환합니다.

시간 복잡도

우리가 작성한 알고리즘의 시간 복잡도는 입력 값 N에 따라 달라집니다. 소수 판별시 sqrt(N)만큼의 시간이 소요되며, 전체적으로 N에서 시작해 최솟값을 찾는 과정까지 포함하면 최악의 경우 O(N√N)의 시간 복잡도를 가집니다.

푸는 과정에서 주의할 점

소수 및 팰린드롬 수를 찾는 과정에서 기본적인 수학과 문자열 변환에 대한 이해가 필요합니다. 또한, C++의 기본 문법 및 자료형에 대한 이해도 필수적입니다. 이 문제를 해결하기 위해 정보를 잘 정리하고, 단계별로 접근하는 연습이 필요합니다.

맺음말

이번 강좌를 통해 소수와 팰린드롬 관련 알고리즘을 이해하고 스스로 구현해보는 기회를 가졌습니다. 이 문제는 실무에서 활용될 수 있는 유용한 알고리즘 중 하나로, 취업 준비 시 유용하게 활용할 수 있습니다. 앞으로도 다양한 알고리즘 문제를 풀어보며 코딩 테스트를 준비해나가길 바랍니다.

작성자: 조광형

날짜: [오늘 날짜]

C++ 코딩테스트 강좌, 세그먼트 트리

최근의 알고리즘 코딩 테스트에서 세그먼트 트리는 자주 등장하는 자료구조 중 하나입니다. 세그먼트 트리는 특정 구간의 합, 최소값, 최대값 등을 효율적으로 계산할 수 있도록 도와주는 자료구조입니다. 이번 글에서는 세그먼트 트리를 사용하는 알고리즘 문제를 살펴보고, 이를 해결하기 위한 과정과 실제 구현 예시를 제공하겠습니다.

문제 설명

주어진 배열에서 구간 [l, r]의 합을 구하는 쿼리를 수행할 수 있는 프로그램을 작성하시오. 입력으로는 배열의 크기 n과 쿼리의 개수 m이 주어지며, 이어서 n개의 정수가 배열로 주어집니다. 각 쿼리는 두 개의 정수 l과 r로 구성되어 있습니다.

문제 예시

입력:
5 3
1 2 3 4 5
1 3
2 4
1 5

출력:
6
9
15

문제 접근 방법

위 문제는 단순히 배열을 순회하여 합계를 계산하는 방법으로도 해결할 수 있지만, 주어진 쿼리의 수가 많고 배열의 크기가 큰 경우 비효율적입니다. 이에 따라 세그먼트 트리를 사용하면 효율적으로 문제를 해결할 수 있습니다.

세그먼트 트리란?

세그먼트 트리는 배열을 구간 단위로 나누어 각 구간의 정보를 저장하는 트리 구조입니다. 이 트리는 다음과 같은 특성을 가지고 있습니다:

  • 각 노드는 배열의 구간을 표현합니다.
  • 각 리프 노드는 배열의 원소를 저장합니다.
  • 각 내부 노드는 자식 노드의 값을 합산하여 저장합니다.

세그먼트 트리를 활용하면 구간의 합을 O(log n) 시간 복잡도로 계산할 수 있습니다. 이는 배열의 원소 수가 많아질수록 그 효율성이 두드러집니다.

세그먼트 트리 구현

이제 세그먼트 트리를 이용하여 문제를 해결해보겠습니다. 다음은 C++로 세그먼트 트리를 구현하는 코드입니다.


#include 
#include 
using namespace std;

class SegmentTree {
private:
    vector tree, arr;
    int n;

public:
    SegmentTree(const vector& input) {
        arr = input;
        n = arr.size();
        tree.resize(4 * n);
        build(0, 0, n - 1);
    }

    void build(int node, int start, int end) {
        if (start == end) {
            // Leaf node
            tree[node] = arr[start];
        } else {
            int mid = (start + end) / 2;
            // Recursively build the segment tree
            build(2 * node + 1, start, mid);
            build(2 * node + 2, mid + 1, end);
            // Internal node will have the sum of the two children
            tree[node] = tree[2 * node + 1] + tree[2 * node + 2];
        }
    }

    int sum(int l, int r) {
        return sum(0, 0, n - 1, l, r);
    }

    int sum(int node, int start, int end, int l, int r) {
        if (r < start || end < l) {
            // range represented by a node is completely outside the given range
            return 0;
        }
        if (l <= start && end <= r) {
            // range represented by a node is completely inside the given range
            return tree[node];
        }
        // range represented by a node is partially inside and partially outside the given range
        int mid = (start + end) / 2;
        int left_child = sum(2 * node + 1, start, mid, l, r);
        int right_child = sum(2 * node + 2, mid + 1, end, l, r);
        return left_child + right_child;
    }
};

int main() {
    int n, m;
    cin >> n >> m;
    vector arr(n);
    for (int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    SegmentTree segment_tree(arr);
    
    for (int i = 0; i < m; ++i) {
        int l, r;
        cin >> l >> r;
        // Adjusting for 0-based indexing
        cout << segment_tree.sum(l - 1, r - 1) << endl;
    }
    
    return 0;
}

코드 분석

위 코드는 아래와 같은 절차로 세그먼트 트리를 구현합니다:

  • 클래스 정의: SegmentTree 클래스를 정의하고 필요한 멤버 변수를 선언합니다. 여기에는 세그먼트 트리를 저장할 tree 벡터와 원본 배열 arr, 배열의 크기 n이 포함됩니다.
  • 생성자: 생성자에서 입력 배열을 받아 세그먼트 트리를 초기화하고 build 메서드를 호출하여 트리를 구축합니다.
  • 트리 구축: build 메서드는 재귀적으로 트리를 구축합니다. 리프 노드는 원본 배열의 원소를 저장하고, 내부 노드는 자식 노드의 합을 저장합니다.
  • 합 계산: sum 메서드는 주어진 구간의 합을 계산합니다. 이 메서드는 노드가 주어진 구간의 범위에 속하는지 확인하고, 속하지 않는 경우 적절한 값을 반환하거나 재귀적으로 합을 계산합니다.
  • 메인 함수: 사용자로부터 배열의 크기와 쿼리 수를 입력받고, 배열을 입력한 뒤 SegmentTree 객체를 생성합니다. 그리고 각 쿼리에 대해 결과를 출력합니다.

결론

세그먼트 트리는 특정 구간의 합을 빠르게 계산할 수 있도록 도와주는 강력한 도구입니다. C++를 사용하여 세그먼트 트리를 구현함으로써, 알고리즘 문제 해결에 필요한 효율성을 높일 수 있었습니다. 이 자료구조는 단순합뿐만 아니라 다양한 쿼리에도 활용할 수 있으므로, 더 많은 연습을 통해 숙달하는 것이 중요합니다.

이제 여러분은 C++에서 세그먼트 트리를 구현하고 사용할 수 있는 기반 지식을 갖추게 되었습니다. 다양한 문제를 해결하면서 이 자료구조의 힘을 확인해보세요.

C++ 코딩테스트 강좌, 선택 정렬

문제 설명

주어진 정수 배열을 오름차순으로 정렬하는 함수를 작성하시오. 이때 사용할 정렬 알고리즘은 선택 정렬(Selection Sort)입니다.

입력

  • 첫 번째 줄에 정수 N이 주어집니다. (1 ≤ N ≤ 1000)
  • 두 번째 줄에 N개의 정수가 주어집니다. (정수 A[i]는 -10000 ≤ A[i] ≤ 10000)

출력

오름차순으로 정렬된 배열을 한 줄에 공백으로 구분하여 출력합니다.

선택 정렬(Selection Sort) 개념 정리

선택 정렬은 가장 간단한 정렬 알고리즘 중 하나로, 주어진 리스트에서 가장 작은 값을 찾아서 맨 앞의 값과 교환하는 방식으로 작동합니다. 이 과정을 리스트의 끝까지 반복하여 정렬된 리스트를 완성하게 됩니다.

선택 정렬의 동작 과정

  1. 현재 리스트에서 가장 작은 값을 찾습니다.
  2. 그 값을 현재 위치의 값과 교환합니다.
  3. 위의 1, 2 단계를 반복하여 리스트를 정렬합니다.

문제 풀이 과정

1. 문제 해결을 위한 이해

문제를 해결하기 위해 우선 배열에서 가장 작은 값을 찾아 맨 앞에 놓고, 그 다음 작은 값을 찾아 두 번째 위치에 놓는 방식으로 진행합니다. 이 과정은 배열의 길이만큼 반복되며, 각 단계에서 가장 작은 값을 찾기 위해 배열의 나머지 부분을 검색해야 합니다.

2. 선택 정렬 알고리즘 구현

이제 셀렉션 정렬 알고리즘을 C++로 구현해 보겠습니다. 먼저 배열을 입력받고, 그런 다음 선택 정렬 알고리즘을 적용하여 정렬한 후 출력을 진행합니다.


#include <iostream>
using namespace std;

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        // 현재 위치를 최소값의 인덱스로 설정
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j; // 최소값이 발견된 경우
            }
        }
        // 현재 위치와 최소값의 위치를 교환
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}

int main() {
    int n;
    cin >> n;
    int arr[n];
    for(int i = 0; i < n; i++) {
        cin >> arr[i];
    }

    selectionSort(arr, n);

    for(int i = 0; i < n; i++) {
        cout << arr[i];
        if (i < n - 1) cout << " ";
    }
    cout << endl;

    return 0;
}
    

3. 코드 설명

각 부분의 코드를 설명하겠습니다.

  • void selectionSort(int arr[], int n): 선택 정렬을 수행하는 함수입니다. 매개변수로 배열과 배열의 크기를 받습니다.
  • for (int i = 0; i < n - 1; i++): 배열을 순회하면서 정렬을 진행합니다.
  • int minIndex = i;: 현재 인덱스에서 최소값의 인덱스를 초기화합니다.
  • if (arr[j] < arr[minIndex]): 현재 값이 최소값보다 작은 경우 새로운 최소값 인덱스를 업데이트합니다.
  • int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp;: 현재 인덱스의 값과 최소값 인덱스의 값을 교환합니다.

4. 예시 실행

다음은 선택 정렬 알고리즘의 예시 실행입니다. 우선 N과 배열 값을 입력합니다.


입력:
5
64 25 12 22 11

출력:
11 12 22 25 64
    

시간 복잡도

선택 정렬의 시간 복잡도는 O(N2)입니다. 모든 요소를 순회하면서 최솟값을 찾아야 하기 때문에 두 개의 중첩 루프가 필요합니다. 따라서 데이터 양이 많으면 성능이 저하될 수 있습니다.

결론

이번 포스트에서는 C++을 사용하여 선택 정렬을 구현하고, 이를 통해 기본적인 정렬 알고리즘의 개념을 익혔습니다. 선택 정렬은 간단하지만 효율이 좋지 않은 알고리즘이므로, 더 큰 데이터에 대해서는 다른 정렬 알고리즘을 고려해야 합니다.

추가 자료

선택 정렬 외에도 많은 정렬 알고리즘이 존재합니다. 다음과 같은 알고리즘을 학습해보시길 권장합니다:

  • 버블 정렬(Bubble Sort)
  • 삽입 정렬(Insertion Sort)
  • 머지 정렬(Merge Sort)
  • 퀵 정렬(Quick Sort)

알고리즘과 데이터 구조에 대해 더 배우고 싶다면, 다음의 자료들을 참조해 보세요:

© 2023 나의 코딩블로그. 모든 권리 보유.