Recursive Call : A Method call in which the method being called is the same as the one making the call (=자기 자신을 호출하는 메소드)
recursive의 가장 큰 원칙은 문제를 쪼개서 풀고 확인하는 작업을 반복하는 것이다.
if (some condition for which answer is knonw) // base case
solution statement
else // general case
recursive function call
n! = n * (n-1)! 이므로 재귀로 표현될 수 있다.
재귀를 반복하다가 1!=1 x 0!에 이르면 0!일 때가 base case로 재귀 호출을 종료하면 된다.
int Factorial(int number)
// Pre: number is assigned and number>=0.
{
if(number==0) // base case
return 1;
else // general case
return number*Factorial(number-1);
}
nCk = n-1Ck + n-1Ck-1 로 나타낼 수 있으므로 재귀로 표현될 수 있다.
int Combinations(int n, int k)
{
if(k==1) // base case 1
return n;
else if (n==k) // base case 2
return 1;
else
return (Combinations(n-1, k)+Combinations(n-1,k-1));
}
x^n = x * x^n-1이므로 n제곱승은 재귀 함수로 표현될 수 있다.
x^0=1일 때가 base case가 된다.
int Power(int x, int n)
// Pre : n>=0. x, n are not both zero.
// Post : Function value = x raised to the power n.
{
if(n==0) // base case
reutnr 1;
else // general case
return (x*Power(x,n-1));
struct ListType
{
int length; // number of elements in the list.
int info[MAX_ITMES];
};
ListType list;
bool ValueInList(ListType list, int value, int startIndex)
{
if (list.info[startIndex] == value) // base case 1
return true;
else if (startIndex == list.length-1) // base case 2
return false;
else // general case
return ValueInList(list, value, startIndex+1);
제일 뒤로 간 다음, 나오면서 Print를 하면 역순으로 출력이 된다. 일반적과 달리
재귀호출을 한 다음 Print를 하는 방식이다.
struct NodeType
{
int info;
NodeType* next;
}
class SortedType
{
public:
private:
NodeType* listData;
};
void RevPrint(NodeType* listPtr)
{
if(listPtr!=NULL) // general case
{
RevPrint(listPtr->next);
std::cout<<listPtr->info<<std::endl; //print this element
}
// base case : if the list is empty, do nothing
}
// Non Recursive Implementaion
template<class ItemType>
void SortedType<ItemType>::RetrieveItem(ItemType& item, bool& found)
{
int midPoint;
int first=0;
int last=length-1;
found false;
while( (first<=last) && !found )
{
midPoint = (first+last)/2;
if (item<info[midPoint])
last=midPoint-1;
else if (item>info[midPoint])
first=midPoint+1;
else
{
found=true;
item=info[midPoint]
}
}
}
Recursive Binart Search
- size factor : the number of elements in ( info[first] ... info[last] )
- base case
(1) If first > last, return false
끝까지 갔는데 찾지 못했으면 false 반환하고 종료
(2) if item==info[midPoint], return true
아이템의 위치를 찾으면 true 반환하고 종료- general case
(1) If item < info[midPoint] , search the first half
찾으려고 하는 값이 중간값보다 작으면 앞을 살핀다.
(2) If item > info[midPoint] , search the second half
찾으려고 하는 값이 중간값보다 크면 뒤를 살핀다.
// Recursive Implementation
template<class ItemType>
bool BinarySearch(ItmeType info[], ItemType item, int fromLoc, int toLoc) // 양쪽 끝을 param으로 받음
{
int mid;
if ( fromLoc > toLoc ) // base case-끝까지 갔는데 없는 경우. false 반환 후 종료.
return false;
else
{
mid=(fromLoc+toLoc)/2;
if(info[mid]==item) // base case-찾은 경우. true 반환 후 종료.
return true;
else if (item<info[mid]) // 작은 경우 앞부분
return BinarySearch(info, item, fromLoc, mid-1);
else // 큰 경우 뒷부분
return BinarySearch(info, item, mid+1, toLoc);
}
}
// Another recursive function
// instruction : 코드 상 위치를 명시
int Func(int a, int b) // instruction 100
{
int result;
if (b==0) // base case
result=0;
else if (b>0) // general case1
result=a+Func(a,b-1); // instruction 50
else //general case2
result=Func(-a,-b); // instruction 70
return result;
template <class ItemType>
void Insert(NodeType<ItemType> *&location, ItmeType item)
{
if( (location==NULL) || (item<location->info) // base case
// 비어있을 때 또는 맨 끝에 들어갈 때 OR 나보다 큰 값 찾았을 때 : STOP
{
NodeType<ItemType<* tempPtr=location;
location=new NodeType<ItemType>;
location->info=item;
location->next=tempPtr;
}
else
Insert(location->next, newItem); // general case
}
template <class ItemType>
void SortedType<ItemType>::InsertItem(ItemType newItem)
{
Insert(listData, newItem);
}
여기서 가장 중요한 것은 reference 타입으로 받은 location의 포인터를 사용한다는 것이다.
* pointer : local variable 값을 주소로 갖는 일반 변수. 새 공간을 잡히고 location 변수에 영향을 주지 않는다.
*& : 파라미터가 location 공간과 동일한 공간을 의미하게 된다. 바뀌면 location도 바뀐다.
templace <class ItemType>
void Delete(NodeType<ItemType>* &location, ItemType item)
// 포인팅(화살표) 변경을 반영하도록 reference 타입으로 받는다. 앞의 next가 내 다음을 pointing 하도록 만든다.
{
if (item==location->info)
{
NodeType<ItemType>* tempPtr=location;
location=location->next;
delete tempPtr;
}
else
Delete(location->next, item);
}
template <class ItemType>
void SortedType<ItemType>::DeleteItem(ItemType item)
{
Delete(listData, item);
}
//Non recursive version - stacks : RevPrint()
// pre. stack을 구현한다.
void ListType::RevPrint()
{
StackType<NodeType*> stack;
NodeType* listPtr;
listPtr=listData;
while(listPtr!=NULL) // Put pointers onto the stack
{
stack.Push(listPtr);
listPtr=listPtr->next;
}
while(!stack.IsEmpty()) // Retrieve pointers in reverse order and print elements
{
listPtr=stack.Top();
stack.Pop();
cout<<listPtr->info;
}
}