本题中创建链表的结点数为5,接下来我们先扣一下递归是什么:
链表的递归实则是使用每调用一次函数就会出现一个形参,当函数使用结束后形参会自动释放这一特点
在本题中,将h指针最初指在NULL即链表尾部,每次使用函数Creatlink创建一个结点
把数组的值赋给这个结点,然后判定数组的值是否完全进入链表中,判定条件为数组长度是否变为0
当长度为0时,从最后一次被调用的函数开始逐层返回
例如当最后一次调用(第五次调用时),一个形参指针指在了NULL上,此时应该执行 # return h #这条语句,语句中的h是第四次调用时产生的形参h.
此处做特殊解释,因为第五次产生的h是在第四次调用该函数产生的,所以返回值应给是返回第四次调用的函数里,这里用Creatlink4来表示
作图来分析一下(**此处申明:Creatlink=Creatlink0=Creatlink1=Creatlink2=Creatlink3=Creatlink4=Creatlink5**)
Creatlink(int a[],int n)
{
Creatlink0 —— h
{
Creatlink1 —— h
}
{
Creatlink2 —— h
}
{
Creatlink3 —— h
}
{
Creatlink4 —— h
}
{
Creatlink5 —— h
}
}
接下来实现的是挂链环节,从第五次调用的形参依次给出函数的返回值
因为第五次是n==0成立,在第四次调用时,此时产生的第五个h=NULL,且没有执行Creatlink5中的h->next=Creatlink(a+1,n-1)这条语句所以直接返回到上一级;
而此时在Creatlink4中的接到来自Creatlink5的返回值,将第五个h的地址赋给第四个h->next,之后依次向前推即可
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}ElemSN;
ElemSN *Creatlink(int a[],int n)
{
ElemSN *h;
h=NULL;
if(n)
{
h=(ElemSN *)malloc(sizeof(ElemSN));
h->data=a[0]; //每一次数组首指针后移一位,数组长度减少一位,都是新数组的首地址
h->next=Creatlink(a+1,n-1);
}
return h;
}
void Printlink(ElemSN *h)
{
if(h)
{
printf("%5d",h->data);
Printlink(h->next);
}
}
void main(void)
{
ElemSN *head;
int a[5]={4,7,8,6,2};
head=Creatlink(a,5);
printf("\t\t链表为:");
Printlink(head);
printf("\n");
}