재귀함수 : 함수 내에서 자기 자신을 다시 호출하는 함수.
=> 동일한 패턴의 작업을 반복해서 진행
* 재귀의 탈출 조건이 반드시 있어야 한다.
1) 팩토리얼 계산
[재귀함수 탈출 조건] : 0!을 구함
#include <stdio.h>
// 팩토리얼 함수
int Factorial(int n) {
if (n == 0)
return 1;
else
return n* Factorial(n - 1);
}
int main(void) {
int n = 5;
printf("%d! = %d", n, Factorial(n));
return 0;
}
2) 거듭제곱값 계산
[재귀함수 탈출 조건] : 0제곱 값을 구함
#include <stdio.h>
// x의 n제곱 값을 구하는 함수
int Power(int x, int n) {
if (n == 0)
return 1;
else if ((n % 2 == 0)) // n이 짝수인 경우
return Power(x * x, n / 2);
else // n이 홀수인 경우
return x * Power(x * x, (n - 1) / 2);
}
int main(void) {
int x = 2;
int n = 7;
printf("%d의 %d제곱 값 : %d", x, n, Power(x, n));
}
3) 피보나치 수열
[재귀함수 탈출 조건] : 피보나치 수열의 첫 번째, 두 번째 값을 구함
#include <stdio.h>
// 피보나치 수열의 n번째 값을 구하는 함수
int Fibo(int n) {
if (n == 1)
return 0;
else if (n == 2)
return 1;
else
return Fibo(n - 1) + Fibo(n - 2); // * 함수 호출 순서 - '+'연산자 왼편에 있는 Fibo 함수 호출이 완료되어야 오른편의 Fibo 함수 호출이 진행 된다.
}
int main(void) {
int k = 10;
// 피보나치 수열 k번째 항까지 출력
for (int i = 1; i <= k; i++)
printf("%d ", Fibo(i));
return 0;
}
4) 이진 탐색 알고리즘
[이진 탐색 알고리즘의 패턴]
탐색 범위의 중앙에 목표 값이 저장되었는지 확인 → 해당 위치에 목표 값이 없다면 탐색 범위를 반으로 줄여서 다시 탐색
[재귀함수 탈출 조건]
- 탐색 성공 (목표 값이 존재)
- 탐색 실패(목표 값이 존재하지 않음) - 탐색 범위의 시작 위치를 의미하는 first가 탐색 범위의 끝을 의미하는 last보다 커지는 경우
#include <stdio.h>
// 이진 탐색 알고리즘으로 탐색 대상에 목표 값이 존재하는 탐색하고 그 위치를 구하는 함수
int BinarySearch(int arr[], int first, int last, int target) {
int mid; //탐색 대상의 중앙
if (first > last) // 탐색 실패
return -1;
mid = (first + last) / 2;
if (arr[mid] == target) // 탐색 성공
return mid; // 탐색된 타켓이 위치한 인덱스 값 반환
else if (target < arr[mid])
return BinarySearch(arr, first, mid - 1, target);
else
return BinarySearch(arr, mid + 1, last, target);
}
int main(void) {
int arr[] = { 1, 3, 5, 7, 9, 11, 13 };
int idx; //목표 값이 위치한 인덱스
int n = 7; //목표 값
idx = BinarySearch(arr, 0, sizeof(arr) / sizeof(int) - 1, n);
if (idx == -1)
printf("탐색 실패 \n");
else
printf("타겟 저장 인텍스 : %d \n", idx);
return 0;
}
cf ) 반복문을 이용하여 구현한 이진 탐색 알고리즘
#include <stdio.h>
// 이진 탐색 알고리즘으로 탐색 대상에 목표 값이 존재하는 탐색하고 그 위치를 구하는 함수
int BinarySearch(int arr[], int len, int target) {
int first = 0; // 탐색 대상의 시작 인덱스
int last = len - 1; // 탐색 대상의 마지막 인덱스
int mid;
while (first <= last) {
mid = (first + last) / 2;
if (target == arr[mid]) // 탐색 성공
return mid;
else {
if (target < arr[mid])
last = mid - 1;
else
first = mid + 1;
}
return -1; // 탐색 실패
}
}
int main(void) {
int arr[] = { 1, 3, 5, 7, 9, 11, 13 };
int idx; //목표 값이 위치한 인덱스
int n = 7; //목표 값
idx = BinarySearch(arr, sizeof(arr) / sizeof(int), n);
if (idx == -1)
printf("탐색 실패 \n");
else
printf("타겟 저장 인덱스: %d \n", idx);
return 0;
}
5) 하노이 타워
[하노이 타워 반복 패턴]

1단계 : 작은 원반 n-1개(맨 아래 원반을 제외한 나머지 원반)를 A에서 B로 이동
2단계 : 큰 원반 1개(맨 아래 원반)를 A에서 C로 이동
3단계 : 작은 원반 n-1개(1단계에서 옮겨진 원반)를 B에서 C로 이동
[재귀함수 탈출 조건] : 이동해야 할 원반의 수가 1개인 경우
#include <stdio.h>
// 하노이타워 구현 함수 : from에 꽂혀있는 num개의 원반을 by를 거쳐 to로 이동
void HanoiTowerMove(int num, char from, char by, char to) {
if (num == 1) {
printf("원반1을 %c에서 %c로 이동 \n", from, to);
}
else {
HanoiTowerMove(num - 1, from, to, by);
printf("원반%d를 %c에서 %c로 이동 \n", num, from, to);
HanoiTowerMove(num - 1, by, from, to);
}
}
int main(void) {
// 막대 A의 원반 3개를 막대 B를 경유하여 막대C로 옮기기
HanoiTowerMove(3, 'A', 'B', 'C');
return 0;
}
'CS > 자료구조(C)' 카테고리의 다른 글
[자료구조] 6. 리스트(List)3 - 원형 연결 리스트 / 이중 연결 리스트 (0) | 2022.10.20 |
---|---|
[자료구조] 5. 리스트(List)2 - 단순 연결 리스트 구현 (0) | 2022.10.17 |
[자료구조] 4. 리스트(List)1 - 리스트ADT / 순차 리스트와 연결 리스트 / 순차 리스트 구현 (0) | 2022.10.17 |
[자료구조] 2. 알고리즘 성능 분석 - 시간 복잡도 분석 / 빅오 표기법 (0) | 2022.10.06 |
[자료구조] 1. 자료구조와 알고리즘, 추상 자료형(ADT) (0) | 2022.10.04 |