主要是求递归模型,递归模型的求解类似于(其实就是)数学中的归纳法。递归模型中应该包含递归体和递归出口两部分。
代码如下:
#include
#define NUM 8
int A[NUM] = { 102,102,32,44,202,32,61,56 };
int min(int a,int b)
{
if (a < b)return a;
else return b;
}
int F(int A[], int i)//使用递归求数组A[]中A[0]~A[i]的最小值
{
if (i == 0)return A[0];
else
{
return min(F(A, i - 1), A[i]);
}
}
int main()
{
printf("F: %d\n", F(A, NUM - 1));
return 0;
}
#include
#include
typedef struct Node {
int data;
struct Node* next;
}Node, * LkList;
void CreatLkList(LkList& L, int n);
void Tranvers_Twd(LkList L);//递归正向遍历
void Tranvers_Bk(LkList L);//递归反向遍历
void DestoryList(LkList& L);
int main()
{
LkList L;
CreatLkList(L, 5);
printf("正向遍历:\n");
Tranvers_Twd(L);
printf("反向遍历:\n");
Tranvers_Bk(L);
printf("销毁链表:\n");
DestoryList(L);
return 0;
}
void CreatLkList(LkList& L,int n)//递归创建不带头结点的单链表
{
if (n == 0)//终止条件
{
L = NULL;
}
else
{
L = (LkList)malloc(sizeof(Node));
if (!L)exit(0);
scanf_s("%d",&(L->data));
CreatLkList(L->next, n - 1);
}
}
void Tranvers_Twd(LkList L)//递归正向遍历
{
if (L == NULL)return;
printf("%d\n",L->data);
Tranvers_Twd(L->next);
}
void Tranvers_Bk(LkList L)//递归反向遍历
{
if (L == NULL)return;
Tranvers_Bk(L->next);
printf("%d\n", L->data);
}
void DestoryList(LkList& L)
{
if (L)
{
DestoryList(L->next);
printf("free:%d\n", L->data);//显示释放过程
free(L);
L = NULL;
}
}
递归函数的位置很重要,它决定了该递归从哪里展开,也就会有不同的效果。
void Tranvers_Twd(LkList L)//递归正向遍历
{
if (L == NULL)return;
printf("%d\n",L->data);
Tranvers_Twd(L->next);
}
void Tranvers_Bk(LkList L)//递归反向遍历
{
if (L == NULL)return;
Tranvers_Bk(L->next);
printf("%d\n", L->data);
}
比如上文的链表的正向遍历和反向遍历,他们的差别只是递归函数的位置不同!我们知道代码是从前往后执行的,如果递归函数是在最后调用(尾递归),我们递归展开一次就会是这样:
void Tranvers_Twd(LkList L)//递归正向遍历
{
if (L == NULL)return;
printf("%d\n", L->data);
if (L->next == NULL)return;
printf("%d\n", L->next->data);
Tranvers_Twd(L->next->next);
}
再展开一次就是这样:
void Tranvers_Twd(LkList L)//递归正向遍历
{
if (L == NULL)return;
printf("%d\n", L->data);
if (L->next == NULL)return;
printf("%d\n", L->next->data);
if (L->next->next == NULL)return;
printf("%d\n", L->next->next->data);
Tranvers_Twd(L->next->next->next);
}
...展开下去就是从L开始一直打印两边中的节点的数据,直到L->next....->next=NULL就会终止。
同样的道理,我们对反向遍历函数Tranvers_Bk展开两次:
void Tranvers_Bk(LkList L)//递归反向遍历
{
if (L == NULL)return;
if (L->next == NULL)return;
if (L->next->next == NULL)return;
Tranvers_Bk(L->next->next->next);
printf("%d\n", L->next->next->data);
printf("%d\n", L->next->data);
printf("%d\n", L->data);
}
可以看到,是从内往外打印的!这就是递归反向遍历链表的道理!
总的来说,递归函数前的是有外入内,递归函数后的是有内出外。
void f()
{
//由外到内
f();//递归体
//由内到外
}