# 삽입 정렬 삽입 정렬(Insertion Sort)은 데이터 집합을 순회하면서 정렬이 필요한 요소를 뽑아 이를 다시 적당한 곳에 삽입해 나가는 알고리즘이다. 마치 뒤섞여 있는 트럼프 카드를 순서대로 정리하는 모습과 같다. 카드를 한 장씩 뽑아 카드의 값에 따라 적절한 곳에 끼워 넣는 것을 반복하다 보면 결국 모든 카드가 순서대로 정리된다. 마찬가지로 데이터 집합에서 요소를 하나씩 뽑아 적절한 곳에 끼워 넣는 것을 반복하다 보면 정렬된 데이터 집합을 얻을 수 있다. 삽입 정렬은 구현이 간단해서 버블 정렬과 함께 프로그래머들에게 애용되는 알고리즘 중 하나다. 성능 또한 버블 정렬과 비슷하다. 이 알고리즘은 아래의 과정을 통해 정렬을 수행한다. 오름차순으로 정렬할 때를 가정한다. 데이터 집합에서 정렬 대상이..
Vitamin Quiz 문제) 버블 정렬은 이미 정렬이 되어 있어도 모든 루프를 돌며 비교를 수행하는 미련한 알고리즘이다. 정렬되어 있는 경우에는 루프를 취소하고 빠져나올 수 있도록 알고리즘을 개선하라. 풀이 플래그(flag) 변수를 하나 사용함으로써 문제를 해결했다. 첫 검사에서 비교를 했는데 바꿀 것이 없었다면 플래그 값은 변함이 없을 것이다. 첫 검사로부터 데이터가 정렬이 되어 있는지를 플래그를 통해 확인한다. /************************************************* ** BubbleSort Vitamin Quiz *************************************************/ #include void BubbleSort(int dataS..
Vitamin Quiz 문제) 아래 예제 프로그램에서 특정 레벨의 모든 노드를 출력하는 함수 LCRS_PrintNodesAtLevel(LCRSNode *Root, int Level)를 작성하라. 함수의 원형은 다음과 같다. void LCRS_PrintNodesAtLevel(LCRSNode *Root, int Level); 풀이 // 이 글은 드래그 및 복붙이 안되므롤 아래 첨부한 파일을 다운받아 보시기 바랍니다. 첫 번째는 교재의 소스코드, 두 번째는 데브맷의 풀이 소스입니다. 이 문제의 핵심은 원하는 레벨의 모든 노드를 출력하기 위해서는 부모노드의 정보를 기억할 필요가 있다는 겁니다. /************************************************* ** LCRSTree Vit..
Vitamin Quiz 문제) 위 예제의 AS_IsFULL(ArrayStack *Stack) 함수를 추가하라. 스택을 생성할 때 정한 용량이 가득 차 있는지 체크하는 기능이다. 함수의 원형은 다음과 같다.int AS_IsFULL(ArrayStack *Stack); 풀이 // 이 글은 드래그 및 복붙이 안되므로 아래 첨부한 파일을 다운받아 보시기 바랍니다. 첫 번째는 교재의 소스코드 및 헤더파일, 두 번째는 데브맷의 풀이입니다. 문제가 굉장히 쉽다. 왜냐하면, 애초에 ArrayStack 구조체를 정의할 때, Capacity라는 변수도 추가해줬기 때문이다. 따라서 스택이 가득 차 있는지 확이하려면 현재 배열에 들어온 원소의 갯수를 나타내는 Top 변수와 Capacity가 같은지 여부만 체크해주면 된다. /*..
Vitamin Quiz 문제) 더블 링크드 리스트를 역순으로 출력하는 함수를 작성해라. 원형은 다음과 같다.void PrintReverse(Node *head); 풀이 // 이 글은 드래그 및 복붙이 안되므로, 최하단에 첨부한 문제풀이 소스코드를 따로 받아보시길 바랍니다./* 교재의 소스 코드 중, 문제풀이에 꼭 필요한 소스코드만 사용했습니다. 또한 데브맷이 임의적으로 변수의 이름과 함수의 이름을 재설정해줬습니다. 가독성과 의미를 고려한 결정이었습니다. 헤더파일 분할 없이 데브맷 풀이.c 에 코드를 담았으며 교재의 원본소스와 문제풀이 답안을 포함한 자체제작 소스 둘 다 최하단에 첨부해놨습니다. */ 맨 마지막에 정의되어 있는 printReverse 함수를 집중적으로 살펴보도록 하자. 나머지는 교재의 소스..
Vitamin Quiz 문제) SLL_insertAfter( ) 함수는 특정 '노드 뒤'에 새로운 노드를 삽입하는 기능을 수행한다. SLL_InsertNewHead( ) 함수는 '헤드 앞'에 새로운 헤드를 삽입할 수 있다. 그렇다면 특정 '노드 앞'에 새로운 노드를 삽입하는 SLL_InsertBefore( )함수도 존재할 것이다. 이 함수를 구현하라. 원형은 다음과 같다.void SLL_InsertBefore( Node **Head, Node *Current, Node *NewHead ); 다음으로 링크드 리스트의 모든 노드를 한 번에 제거하는 SLL_DestroyAllNodes( ) 함수를 작성하라. 원형은 다음과 같다.SLL_DestroyAllNodes( Nodes **List ); 풀이 // 이 글..
# 선택 정렬 [Selection sort] // 소스코드는 최하단에 첨부되어 있습니다. (게시글 복붙, 드래그 불가) 만약 우리가 1보다 크거나 같은 모든 정수에 대하여 크기 순으로 정렬하는 프로그램을 작성한다고 가정해보자. 그 때 생각할 수 있는 기본 아이디어는 배열을 사용하는 것이고, 둘째로 가장 작은 수를 찾아 배열의 가장 왼쪽 (index 0)으로 이동시키는 작업이다. /************************************************* ** Selection sort program example *************************************************/ #include #include #include // 배열의 최대크기 제한 #define..
# 이진 탐색 트리란? // 이 글은 복붙 및 드래그가 불가하니 밑에 소스파일을 다운로드 해주세요. 이진 탐색 트리(binary search tree)는 이진 트리 기반의 탐색을 위한 자료 구조이다. 이진 탐색 트리의 조건에는 아래와 같이 4개의 조건이 있다. 모든 노드의 키는 유일하다. // 중복된 데이터를 갖는 노드가 없다는 뜻이다. 여기서 키의 의미는 노드 안에 들어 있는 데이터 값을 의미한다. 왼쪽 서브 트리의 키들은 루트의 키보다 작다. // 예를 들어 루트노드의 데이터가 5라고 하면, 왼쪽 서브트리에는 무조건 5보다 작은 값들만 존재해야 한다. 오른쪽 서브 트리의 키들은 루트의 키보다 크다. // 위와 같은 원리로 오른쪽에는 루트의 데이터 값보다 더 큰 값들만 존재한다. 왼쪽과 오른쪽 서브 트..
# 스레드 이진트리 // 이 글은 드래그 및 복붙이 되지 않습니다. 소스파일은 하단에 첨부되어 있습니다. 이진트리 순회는 순환호출을 사용한다. 하지만, 순환호출은 반복문에 의해 훨씬 비효율적이다. 그리고 이 비효율성은 트리의 높이가 커질수록, 노드의 갯수가 많아질 수록 더 커진다. 따라서 이진트리의 순회를 순환 호출 없이 좀 더 효율적을 할 수 없을까? 라는 고민을 하게 된다. 우선 이진트리의 노드에는 많은 NULL 링크들이 존재한다. 구체적으로 이 사실을 살펴보도록 하자. /* 일반식으로서의 의미를 지니기 위해 n이라고 쓰지만, 실제로 논리를 따라 갈 때는 그림과 같이 n = 7 이라 생각하자. */ 트리의 노드 개수가 n개 라고 가정해보자. 각 노드당 2개의 링크가 존재하므로 (NULL도 포함) 총 ..
# 포인터(Pointer) 포인터는 C언어의 가장 기본이라고 할 수 있다. 포인터는 C에 존재하는 모든 자료형에 대해 존재하는데, 예를 들면 int에 대한 포인터, char에 대한 포인터, float에 대한 포인터 등의 형태로 사용된다. 포인터의 본질은 메모리의 주소값을 가진다는 점이다. 포인터에 관련해서는 아래에 보이는 두 개의 중요한 연산자가 있다.& 주소 연산자 (the address operator)* 간접지정 연산자 (the dereferencing or indirection operator) 이 연산자들의 의미를 살펴보기 위해 아래와 같이 변수를 선언했다고 해보자. int i, *pi; // int i; int *pi; 이 두문장을 따로 작성한 것과 동일하다. 위와 같이 쓴 이유는 간결성을 위..
- Total
- Today
- Yesterday