C语言中带递归的单链表删除函数
我正在为c语言的一个项目制作一份学生名单 程序中的函数是3 insert=将学生插入列表 打印=打印出可用的学生 delete=从列表中删除一名学生 我已经创建了这个程序,它可以很好地使用这三个函数 现在,我想使用递归创建相同的列表C语言中带递归的单链表删除函数,c,recursion,linked-list,C,Recursion,Linked List,我正在为c语言的一个项目制作一份学生名单 程序中的函数是3 insert=将学生插入列表 打印=打印出可用的学生 delete=从列表中删除一名学生 我已经创建了这个程序,它可以很好地使用这三个函数 现在,我想使用递归创建相同的列表 我已经使print函数递归,它正在工作 现在我正试图使delete函数以同样的方式工作 不幸的是,我没能让它工作 在下面的代码中,如果您运行它,您将看到它仅在您不尝试删除列表上的最后一个节点并且您不告诉它删除一个不存在的节点时才起作用 #include &l
我已经使print函数递归,它正在工作 现在我正试图使delete函数以同样的方式工作 不幸的是,我没能让它工作
在下面的代码中,如果您运行它,您将看到它仅在您不尝试删除列表上的最后一个节点并且您不告诉它删除一个不存在的节点时才起作用
#include <stdio.h>
#include <stdlib.h>
typedef struct tf *tp;
struct tf{
int am;
double gr;
tp next;
};
tp head, tail, temp, aux;
void insert1 (tp *h, tp t);
void print1(tp h);
void delete1(tp *h,int da);
int main()
{
char fry, fry2;
int am;
fry = 'a';
head = NULL;
tail = NULL;
while (fry != 'q')
{
printf("\n character given is %c\n", fry);
if (fry != 'q')
{
printf("new choice\n");
fry = 'a';
fflush(stdin);
fry = getchar();
getchar();
if (fry == 'q')
printf("quit\n");
if (fry == 'i')
{
fry2 = fry;
printf(" insert new student number am\n");
insert1(&head,tail);
fry = fry2;
}
if (fry == 'd')
{printf(" delete \n");
printf(" am number of student to be deleted\n");
scanf("%d", &am);
delete1(&head,am);
}
if (fry == 'p')
{
printf("\n printing\n");
print1(head);
}
}
}
}
void insert1 (tp *h, tp t)
{
tp te, a;
int da;
te = (tp)malloc(sizeof(struct tf));
printf(" am number for the new insert\n");
scanf("%d", &da);
getchar();
te->am = da;
te->next = NULL;
printf("am number is %d",te->am);
if ((*h != NULL) && (te->am < (*h)->am))
{
te->next = *h;
*h = te;
}
if((*h != NULL) && ((*h)->next != NULL) && (te->am > (*h)->am))
{
a=*h;
while((a->next != NULL) && (a->next->am < te->am))
{
a= a->next;
}
te->next = a->next;
a->next = te;
}
if((*h != NULL) && ((*h)->next == NULL) && (te->am > (*h)->am))
{
(*h)->next = te;
}
if(*h == NULL)
{
printf("\n head is null");
*h = te;
t = te;
}
}
void print1(tp h)
{
tp a;
a=h;
if (a==NULL)
return;
printf("%d\n",a->am);
print1(a->next);
}
void delete1(tp *h,int da)
{
tp a= *h,t= *h,temp = NULL;
if ((*h) != NULL)
{
if ((*h)->am!=da)
{
if (a->next->am != da && a->next!=NULL)
{
delete1(a->next,da);
}
else
{
if (a->next==NULL)
{
printf("am not found\n");
return;
}
else
{
temp = a->next;
a->next = a->next->next;
free(temp);
}
}
}
else
{
a = (*h);
(*h)= (*h)->next;
free(a);
}
}
else
{
printf("empty list");
}
}
#包括
#包括
typedef结构tf*tp;
结构tf{
国际调幅;
双gr;
tp-next;
};
tp头、尾、温度、辅助;
空隙插入物1(tp*h,tp t);
无效打印1(tp h);
void delete1(tp*h,int da);
int main()
{
炒焦,油炸2;
国际调幅;
fry='a';
head=NULL;
tail=NULL;
而(fry!=“q”)
{
printf(“\n给定字符为%c\n”,fry);
如果(fry!=“q”)
{
printf(“新选择”);
fry='a';
fflush(stdin);
fry=getchar();
getchar();
如果(fry='q')
printf(“退出”);
如果(fry='i')
{
fry2=fry;
printf(“插入新学生编号am\n”);
插入件1(头部和尾部);
fry=fry2;
}
如果(fry='d')
{printf(“删除”);
printf(“要删除的am学生编号\n”);
scanf(“%d”和&am);
删除1(和头部,am);
}
如果(fry='p')
{
printf(“\n打印\n”);
打印1(头);
}
}
}
}
空心插件1(tp*h,tp t)
{
tp-te,a;
int da;
te=(tp)malloc(sizeof(struct-tf));
printf(“新插入的am编号\n”);
scanf(“%d”、&da);
getchar();
te->am=da;
te->next=NULL;
printf(“am编号为%d”,te->am);
如果((*h!=NULL)和&(te->am<(*h)->am))
{
te->next=*h;
*h=te;
}
如果((*h!=NULL)&&(*h)->next!=NULL)&&&(te->am>(*h)->am))
{
a=*h;
而((a->next!=NULL)&&(a->next->amam))
{
a=a->next;
}
te->next=a->next;
a->next=te;
}
如果((*h!=NULL)&&(*h)->next==NULL)&&&(te->am>(*h)->am))
{
(*h)->next=te;
}
如果(*h==NULL)
{
printf(“\n头为空”);
*h=te;
t=te;
}
}
无效打印1(tp h)
{
tpa;
a=h;
如果(a==NULL)
返回;
printf(“%d\n”,a->am);
打印1(a->下一步);
}
无效删除1(tp*h,内部da)
{
tpa=*h,t=*h,temp=NULL;
如果((*h)!=NULL)
{
如果((*h)->am!=da)
{
如果(a->next->am!=da&&a->next!=NULL)
{
delete1(a->next,da);
}
其他的
{
如果(a->next==NULL)
{
printf(“未找到am\n”);
返回;
}
其他的
{
temp=a->next;
a->next=a->next->next;
免费(临时);
}
}
}
其他的
{
a=(*h);
(*h)=(*h)->下一步;
免费(a);
}
}
其他的
{
printf(“空列表”);
}
}
如您所见,我希望delete函数通过查找给定的am编号来删除节点,因此它将首先搜索列表以查找am编号是否存在
如果有人能告诉我如何使用删除功能,我将不胜感激。有几件事正在进行。这一行:
if (a->next->am != da && a->next!=NULL) ...
应该交换条件,否则您可以访问a->next
,而不首先验证它是否为NULL
。辅助变量a
和其他临时变量令人困惑,而不是有用的
将head
作为指针传递给delete1
函数,以便更新head。但这不仅仅影响头部:这增加了一个间接层次,考虑到您的迭代
对于迭代调用,这意味着您必须传递存储对当前节点的引用的指针的地址,(*h)->next
。开始时,这是负责人的地址。在后续迭代中,这是上一个节点的下一个指针的地址
也没有必要考虑各种情况。代码可以简单到:
void delete1(tp *h, int da)
{
if (*h != NULL) {
if ((*h)->am == da) {
tp next = (*h)->next;
free(*h);
*h = next;
return;
}
delete1(&(*h)->next, da);
}
}
递归调用发生在函数末尾,或者根本不发生。这意味着您可以将代码重写为循环:
void delete1(tp *h, int da)
{
while (*h != NULL) {
if ((*h)->am == da) {
tp next = (*h)->next;
free(*h);
*h = next;
return;
}
h = &(*h)->next;
}
}
这将在大型列表上为您节省一些堆栈空间。您的insert1
功能也可以进行清理和简化。非常感谢您的回复我是一个乞丐,我正在从我的mis学习