💡 재귀함수란?
함수 안에 함수 본인을 다시 호출하는 것을 의미한다
이러한 재귀함수는 자신의 로직을 내부적으로 반복하다, 일정 조건이 만족되면
함수가 종료되고 반환 값이 있으면 반환 값을 반환한다
echo 5*10; // 출력 : 50
function multiply($a, $b) {
return $a * $b;
}
echo multiply(5, 10); // 출력 : 50
function recusiveMultiply($a, $b) {
if($a == 0 || $b == 0) {
return 0;
}
return $a + recusiveMultiply($a, $b - 1);
}
function factorial($n) {
$result = 1;
for($i = 2; $i <= $n; $i++) {
$result *= $i;
}
return $result;
}
echo factorial(5); // 출력 : 120
function recursiveFactorial($n) {
if($n <= 1) {
return 1;
}
return $n * recursiveFactorial($n - 1);
}
echo recursiveFactorial(5); // 출력 : 120
function fibonacci($n) {
$a = 0;
$b = 1;
for($i = 0; $i < $n; $i++) {
$temp = $a;
$a = $b;
$b = $temp + $b;
}
return $a;
}
echo fibonacci(10); // 출력 : 55
OR
function fibonacci($n) {
if($n <= 1) {
return $n;
}
$fib = array(0, 1);
for($i = 2; $i <= $n; $i++) {
$fib[$i] = $fib[$i - 1] + $fib[$i - 2];
}
return $fib[$n];
}
echo fibonacci(10); // 출력 : 55
function recursiveFibonacci($n) {
if($n <= 1) {
return $n;
} else {
return recursiveFibonacci($n - 1) + recursiveFibonacci($n - 2);
}
}
echo recursiveFibonacci(10); // 출력 : 55
function hanoi($n) {
$moves = pow(2, $n) - 1;
$stack = array();
$stack[] = array('n' => $n, 'disk' => $n, 'from' => 'A', 'to' => 'C', 'aux' => 'B');
while(!empty($stack)) {
$task = array_pop($stack);
$n = $task['n'];
$disk = $task['disk'];
$from = $task['from'];
$to = $task['to'];
$aux = $task['aux'];
if($n == 1) {
echo "$disk 번 원반을 $from 에서 $to 로 이동" . "<br>";
} else {
$stack[] = array('n' => $n - 1, 'disk' => $n - 1, 'from' => $aux, 'to' => $to, 'aux' => $from);
$stack[] = array('n' => 1, 'disk' => $n, 'from' => $from, 'to' => $to, 'aux' => $aux);
$stack[] = array('n' => $n - 1, 'disk' => $n - 1, 'from' => $from, 'to' => $aux, 'aux' => $to);
}
}
return $moves;
}
echo "총 이동 횟수 : " . hanoi(3);
출력 :
/*
1 번 원반을 A 에서 C 로 이동
2 번 원반을 A 에서 B 로 이동
1 번 원반을 C 에서 B 로 이동
3 번 원반을 A 에서 C 로 이동
1 번 원반을 B 에서 A 로 이동
2 번 원반을 B 에서 C 로 이동
1 번 원반을 A 에서 C 로 이동
총 이동 횟수 : 7
/*
function hanoi($n, $from, $to, $aux) {
if($n == 1) {
echo "1번 원반을 $from 에서 $to 로 이동" . "<br/>";
return;
}
hanoi($n - 1, $from, $aux, $to);
echo "$n 번 원반을 $from 에서 $to 로 이동" . "<br/>";
hanoi($n - 1, $aux, $to, $from);
}
hanoi(3, 'A', 'C', 'B');
출력 :
/*
1 번 원반을 A 에서 C 로 이동
2 번 원반을 A 에서 B 로 이동
1 번 원반을 C 에서 B 로 이동
3 번 원반을 A 에서 C 로 이동
1 번 원반을 B 에서 A 로 이동
2 번 원반을 B 에서 C 로 이동
1 번 원반을 A 에서 C 로 이동
*/
function mergeSort($array)
{
$n = count($array);
$size = 1;
while ($size < $n) {
for ($start = 0; $start < $n; $start += $size * 2) {
$mid = $start + $size;
$end = min($start + $size * 2, $n);
merge($array, $start, $mid, $end);
}
$size *= 2;
}
return $array;
}
function merge(&$array, $start, $mid, $end)
{
$left = array_slice($array, $start, $mid - $start);
$right = array_slice($array, $mid, $end - $mid);
$i = 0;
$j = 0;
$k = $start;
while ($i < count($left) && $j < count($right)) {
if ($left[$i] <= $right[$j]) {
$array[$k] = $left[$i];
$i++;
} else {
$array[$k] = $right[$j];
$j++;
}
$k++;
}
while ($i < count($left)) {
$array[$k] = $left[$i];
$i++;
$k++;
}
while ($j < count($right)) {
$array[$k] = $right[$j];
$j++;
$k++;
}
}
$array = array(64, 34, 25, 12, 22, 11, 90);
$sortedArray = mergeSort($array);
echo '정렬 후 : ' . implode(",", $sortedArray);
// 출력 : 정렬 후 : 11,12,22,25,34,64,90
function mergeSort($array)
{
if(count($array) <= 1) {
return $array;
}
$mid = floor(count($array) / 2);
$left = array_slice($array, 0, $mid);
$right = array_slice($array, $mid);
$left = mergeSort($left);
$right = mergeSort($right);
return merge($left, $right);
}
function merge($left, $right)
{
$result = array();
$i = 0;
$j = 0;
while($i < count($left) && $j < count($right)) {
if($left[$i] < $right[$j]) {
$result[] = $left[$i];
$i++;
}else{
$result[] = $right[$j];
$j++;
}
}
while($i < count($left)) {
$result[] = $left[$i];
$i++;
}
while($j < count($right)) {
$result[] = $right[$j];
$j++;
}
return $result;
}
$array = array(64, 34, 25, 12, 22, 11, 90);
$sortedArray = mergeSort($array);
echo '정렬 후 : ' . implode(",", $sortedArray);
// 출력 : 정렬 후 : 11,12,22,25,34,64,90
function quickSort($array)
{
$stack = array();
array_push($stack, 0, count($array) - 1);
while (!empty($stack)) {
$end = array_pop($stack);
$start = array_pop($stack);
if ($start >= $end) continue;
$pivot = $array[$end];
$i = $start - 1;
for ($j = $start; $j < $end; $j++) {
if($array[$j] <= $pivot) {
$i++;
$temp = $array[$i];
$array[$i] = $array[$j];
$array[$j] = $temp;
}
}
$i++;
$temp = $array[$i];
$array[$i] = $array[$end];
$array[$end] = $temp;
array_push($stack, $start, $i - 1);
array_push($stack, $i + 1, $end);
}
return $array;
}
$array = array(64, 34, 25, 12, 22, 11, 90);
$sortedArray = quickSort($array);
echo '정렬 후 : ' . implode(",", $sortedArray);
function quickSort($array)
{
if (count($array) <= 1) {
return $array;
}
$pivot = $array[0];
$left = array();
$right = array();
for ($i = 1; $i < count($array); $i++) {
if ($array[$i] < $pivot) {
$left[] = $array[$i];
} else {
$right[] = $array[$i];
}
}
return array_merge(quickSort($left), array($pivot), quickSort($right));
}
$array = array(64, 34, 25, 12, 22, 11, 90);
$sortedArray = quickSort($array);
echo '정렬 후 : ' . implode(",", $sortedArray);
function gcd($a, $b)
{
while($b != 0) {
$temp = $b;
$b = $a % $b;
$a = $temp;
}
return $a; // 출력 : 5
}
function recursiveGCD($a, $b)
{
if($b == 0) return $a;
return recursiveGCD($b, $a % $b);
}
function power($base, $exponent)
{
$result = 1;
while($exponent > 0) {
if($exponent % 2 == 1) {
$result *= $base;
}
$exponent = (int)($exponent / 2);
$base *= $base;
}
return $result;
}
echo power(2, 3) . "<br>"; // 출력 : 2^3 = 8
function recursivePower($base, $exponent)
{
if ($exponent == 0) return 1;
if ($exponent % 2 == 0) {
$half = power($base, $exponent / 2);
return $half * $half;
}
return $base * recursivePower($base, $exponent - 1);
}
echo recursivePower(2, 3) . "<br>"; // 출력 : 2^3 = 8
// 공통활용
class Node
{
var $value = null;
var $left = null;
var $right = null;
function __construct($value)
{
$this->value = $value;
}
}
$root = new Node(1);
$root->left = new Node(2);
$root->right = new Node(3);
$root->left->left = new Node(4);
$root->left->right = new Node(5);
$root->right->left = new Node(6);
$root->right->right = new Node(7);
$root->left->left->left = new Node(8);
$root->left->left->right = new Node(9);
function inorderTraversal($root)
{
$stack = array();
$current = $root;
$result = array();
while ($current != null || !empty($stack)) {
while ($current != null) {
array_push($stack, $current);
$current = $current->left;
}
$current = array_pop($stack);
$result[] = $current->value;
$current = $current->right;
}
return $result;
}
$result = inorderTraversal($root);
echo implode(", ", $result);
// 출력 : 8 4 9 2 5 1 6 3 7
function recursiveInorderTraversal($root) {
if($root == null) return;
recursiveInorderTraversal($root->left);
echo $node->value . " ";
recursiveInorderTraversal($root->right);
}
// 출력 : 8 4 9 2 5 1 6 3 7
1
/ \
2 3
/ \ / \
4 5 6 7
/ \
8 9
// 왼쪽 하위 트리를 순회 후 루트노드를 방문한다
* 중위 순회 : 8 -> 4 -> 9 -> 2 -> 5 -> 1 -> 6 -> 3 -> 7
// 루트노드 부터 왼쪽을 기준으로 따라 내려간다
전위 순회 : 1 -> 2 -> 4 -> 8 -> 9 -> 5 -> 3 -> 6 -> 7
// 가장 밑에서 부터 시작되고 루트노드를 마지막에 방문한다
후위 순회 : 8 -> 9 -> 4 -> 5 -> 2 -> 6 -> 7 -> 3 -> 1
// 루트노드 부터 레벨 별 왼쪽 오른쪽 순
층별 순회 : 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9
function binarySearch($array, $x)
{
$left = 0;
$right = count($array) - 1;
while ($left <= $right) {
$mid = $left + (int)(($right - $left) / 2);
if ($array[$mid] == $x) return $mid;
if ($array[$mid] < $x) {
$left = $mid + 1;
}else {
$right = $mid - 1;
}
}
return -1;
}
$array = array(1, 3, 5, 7, 9, 11, 13, 15);
$x = 7;
$result = binarySearch($array, $x);
if ($result == -1) {
echo '찾을 수 없습니다';
}else {
echo "$result 번째 인덱스에 있습니다";
}
// 출력 : 3 번째 인덱스에 있습니다
function recursiveBinarySearch($array, $left, $right, $x)
{
if($right >= $left) {
$mid = $left + floor(($right - $left) / 2);
if ($array[$mid] == $x) return $mid;
if ($array[$mid] > $x) {
return recursiveBinarySearch($array, $left, $mid - 1, $x);
}
return recursiveBinarySearch($array, $mid + 1, $right, $x);
}
return -1;
}
$array = array(1, 3, 5, 7, 9, 11, 13, 15);
$x = 7;
$result = recursiveBinarySearch($array, 0, count($array) - 1, $x);
if ($result == -1) {
echo '찾을 수 없습니다';
}else {
echo "$result 번째 인덱스에 있습니다";
}
// 출력 : 3 번째 인덱스에 있습니다
function listFiles($dir) {
$stack = [$dir];
$files = [];
while (!empty($stack)) {
$currentDir = array_pop($stack);
$entries = scandir($currentDir);
foreach ($entries as $entry) {
if ($entry != '.' && $entry != '..') {
$path = $currentDir . '/' . $entry;
if (is_dir($path)) {
array_push($stack, $path);
} else {
$files[] = $path;
}
}
}
}
return $files;
}
function listFiles($dir) {
$files = scandir($dir);
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
if (is_dir("$dir/$file")) {
listFiles("$dir/$file");
} else {
echo "$dir/$file\n";
}
}
}
}