첫째는 SelectionSort, 선택 정렬이다.


원리

1. 0부터 끝요소까지 반복한다.( current < N )

2. 현재요소( current )와 나머지 요소 중 가장 작은 값을 비교하여 더 작다면 교환이 일어난다.



특징

1. 가장 작은 값을 찾는 과정에서 비교는 여러번 일어나지만 실제로 교환은 한번만 일어 나므로 범위가 작을경우 유리하다.

2. 데이터양이 큰 경우 매번 작은 값을 찾기 때문에 매우 느리다.


연산시간

1. 최선의 경우 비교횟수 : N - 1 ( 정렬이 이미 되어 있는 경우 )

2. 최악의 경우 비교횟수 :N * (N - 1) / 2 ( 역순으로 정렬되어 있는 경우 )

- 처음에는 가장 작은 값을 찾기위해 (N - 1) 번 비교할 것이며 하나씩 정렬 될 때마다 -1 씩 하여 끝에는 1번 비교하게 될 것이다. 

즉, 비교횟수는 [ (N - 1) + (N - 2) + (N - 3) ... 1 ]이다. 

식으로 나타내면   = n(n-1) / 2 이며 O표기법으로는 O(n^2)이 된다.


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//SELECTIONSORT
 
void SelectionSort(int* array, int size)
{
    for (int i = 0; i < size; i++)         // i == (0 ~ size)
    {
        for (int j = i; j < size; j++){    // j == (i ~ size)
            if (array[i] > array[j])       // (i) > (j) 이면 교환
            {
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
}
int const MAX = 5;                        // Max 값
int g_arr[MAX] = { 0, };                  // 배열 초기화
int main()
{
    printf("========정렬전========\n");
    //AscendingNumber(g_arr, MAX);        // 순열 배열 생성
    //DescendingNumber(g_arr, MAX);       // 역순 배열 생성
    RandomNumber(g_arr, MAX);             // 랜덤 배열 생성
 
    PrintNumber(g_arr, MAX);             // 배열 출력
    printf("\n");
    clock_t start = clock();             // 시작 시간
    SelectionSort(g_arr, MAX);            // SelectionSort
    clock_t end = clock();                // 끝 시간
 
    printf("========정렬후========\n");
    PrintNumber(g_arr, MAX);             // 배열 출력
    printf("\nTime : %f\n", ((double)(end - start)) / CLOCKS_PER_SEC);
}
cs


결과


시간

시간은 MAX 값 100,000 을 기준으로 측정하였다.

랜덤 배열 : 31.60
역순 배열 : 19.13
순열 배열 : 13.20


결론

선택정렬은 가장 직관적인 정렬인것 같다. (최소값을 앞에 정렬하는 것이기 때문)

또 10000개 이하 개수에 대해서는 비교하는 것에 비해 교환횟수가 적기 때문에 빠른 속도를 나타낸다.(10000개 기준 0.64초)

하지만 O(n^2)의 알고리즘 답게 요소가 많아질 수록 응답 시간이 길어지는 것이 확실히 보인다.

'All > Algorithm' 카테고리의 다른 글

InsertionSort  (0) 2016.01.03
BubbleSort  (0) 2016.01.02
Sort Algorithm  (0) 2015.12.28
JUMPGAME_알고리즘  (0) 2015.12.28
JUMPGAME_문제  (0) 2015.12.28

메모리 누수를 검사하는 방법에 대한 포스팅

프로그래밍을 하다보면 메모리를 할당하고 해제하는 것을 잊어 버리는 경우가 생기기 마련이다. 

1
2
3
4
5
6
7
8
#include <iostream>
 
int main()
{
    int * pA = new int(10);    // 메모리 할당
    std::cout << *pA << std::endl// 사용
    //delete pA; // 메모리 해제
}
cs

위의 코드는 메모리릭이 나고 있다. 작은 프로그램의 경우 찾기 쉽겠지만 조금이라도 규모가 있다면 찾기 매우 어렵다. 

이때 해결하는 여러방법이 있겠지만 그 중 어떤 메모리가 어디서누수 되었는지 알 수 있는 방법이 있다.
코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <crtdbg.h>
 
int main()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    //_CrtSetBreakAlloc(151); //여기에 넘버를 넣는다.
 
    int * pA = new int(10);
    std::cout << *pA << std::endl;
    //delete pA;
 
    _CrtDumpMemoryLeaks();
}
cs

위의 코드를 실행시키면 출력창에 아래와 같이 출력된다.

1
2
3
4
5
Detected memory leaks!
Dumping objects ->
{151} normal block at 0x005BCB784 bytes long.
 Data: <    > 0A 00 00 00 
Object dump complete.
cs


이때 151이라는 숫자를 _CrtSetBreakAlloc(151) 함수안에 대입하고 다시 실행하면 아래와 같이 실행 중에 해당 메모리가 할당되는 위치에 브레이크가 걸린다.


이로써 메모리 누수를 검사하는 방법을 알아보았다.

+  _CrtDumpMemoryLeaks(); 은 반드시 프로그램의 마지막 위치에서 호출해야한다.

'All > C++' 카테고리의 다른 글

자주 사용하는 STL function  (0) 2016.11.28
operator new / operator delete  (0) 2016.03.14
가변인자 로그 출력함수  (0) 2015.12.29
RValue와 LValue  (2) 2015.12.28
문장줄이기  (0) 2015.12.28

매번 새프로젝트를 생성할 때마다 절실하게 필요한 몇몇 함수가 있는데 그 중 하나가 로그 출력 함수인 것같다.

아래는 윈도우 기반의 가변인자 로그출력, 메시지 박스 출력, 스트링 합성 함수이다. 
유니코드와 멀티바이트 모두에서 사용 가능하도록 구현하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <stdarg.h>
#include <tchar.h>
#include <Windows.h>
#define DEBUG_MODE 1
typedef std::basic_string<TCHAR> tstring;
 
tstring MakeString(const TCHAR* str, ...){
 
    va_list args;
    int len;
    // 시작.
    va_start(args, str);
 
    // 가변인자로 이루어진 문자열의 크기를 구한다.
    len = _vsctprintf(str, args) + 1// _vscprintf doesn't count terminating '\0'
 
    // 위에서 구한 크기+1만큼 buffer에 메모리를 할당한다.
    TCHAR* buffer = new TCHAR[len + 1];
 
    // 문자열을 buffer에 입력한다.
    _vstprintf(buffer,  str, args);
    
    // 끝.
    va_end(args);
 
    tstring s(buffer);
 
    delete[](buffer);
 
    return s;
}
 
void CLog(const TCHAR* str, ...)
{
#if(DEBUG_MODE >= 1)
    va_list args;
    int len;
    // 시작.
    va_start(args, str);
 
    // 가변인자로 이루어진 문자열의 크기를 구한다.
    len = _vsctprintf(str, args) + 1// _vscprintf doesn't count terminating '\0'
 
    // 위에서 구한 크기+1만큼 buffer에 메모리를 할당한다.
    TCHAR* buffer = new TCHAR[len];
 
    // 문자열을 buffer에 입력한다.
    _vstprintf(buffer, str, args);
 
    // 끝.
    va_end(args);
 
    OutputDebugString(buffer);
    OutputDebugString(_TEXT("\n"));
 
    delete[](buffer);
#endif
}
 
 
void CLogBox(TCHAR * szCaption, TCHAR * szFormat, ...)
{
    // 가변인자로부터 문자열 얻기.
    va_list args;
    int len;
    // 시작.
    va_start(args, szFormat);
 
    // 가변인자로 이루어진 문자열의 크기를 구한다.
    len = _vsctprintf(szFormat, args) + 1// _vscprintf doesn't count terminating '\0'
 
    // 위에서 구한 크기+1만큼 buffer에 메모리를 할당한다.
    TCHAR* buffer = new TCHAR[len + 1];
 
    // 문자열을 buffer에 입력한다.
    _vstprintf(buffer, szFormat, args);
 
    // 끝.
    va_end(args);
    MessageBox(NULL, buffer, szCaption, MB_OK);
 
    delete[](buffer);
}
 
void main()
{
    tstring msg = MakeString(_TEXT("%s"), _TEXT("안녕하세요."));
    CLog(_TEXT("%s"), msg.c_str());
    CLogBox(_TEXT("알림"), _TEXT("%s"), _TEXT("메시지 박스 출력"));
}
 
cs


'All > C++' 카테고리의 다른 글

자주 사용하는 STL function  (0) 2016.11.28
operator new / operator delete  (0) 2016.03.14
메모리 누수 검사  (0) 2015.12.29
RValue와 LValue  (2) 2015.12.28
문장줄이기  (0) 2015.12.28

+ Recent posts