这道题用c语言重写的正确答案在这里
这道题的话,亮点在递归上。既然是递归,我们就要考虑,递归基是什么,很明显,这一题的递归基也就是当指向元素的指针,指向为NULL的时候,我们就直接返回头节点即可
这道题我是这么一个思路,然后让人棘手的就是,在递归的时候如何进行删除?我们知道在c语言的删除中是需要有这个节点的前驱的,不然的话就没法通过前驱删除。
还有一种不需要通过前驱的删除方法,就是假设我们要删除的是p点,我们令
p -> data = p->next->data
p->next = p->next->next;
通过将其后面一个节点的值赋值给它,然后删除后一个结点即可。
?但是这有一个大大的问题,就是说,如果你要删除的元素是最后一个元素的话,就会因为指针越界而报错,目前我不知道如何来解决
课本上的答案是这样的(给的应该是一个c++的程序)
void Del_X_3 (Linklist &L, ElemType x) {
//递归实现在单链表L中删除值为x的结点
LNode *p; //p指向待删除结点
if (L==NULL) //递归出口
return;
if (L->data==x) { //若L所指结点的值为x
p=L; //删除*L,并让L指向下一结点
L=L->next;
free(p);
Del_X_3(L,x) ; //递归调用
}else //若L所指结点的值不为x
Del_X_3 (L->next, x) ; //递归调用
}
首先:c语言没有引用,只有c++才有,只有指针
另外:c++中的指针可以用c的指针的指针来代替,不过,怪我才疏学浅,这一块还是个短板。c++也不太会,哎~
先挖个坑,把学习 c++ 和c语言指针的指针提上日程,等学完以后再填吧
代码:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//递归删除不带头节点的单链表L中所有值为x的结点
typedef struct Node
{
int data;
struct Node* next;
}Node,*LinkList;
//创建一个不带头节点的链表 返回链表的头指针
Node* Init_List()
{
Node* head = (Node*)malloc(sizeof(Node));
assert(head);
int first,size;
printf("please enter list sizes: ");
scanf("%d",&size);
printf("please enter list elements: ");
scanf("%d",&first);
head->data = first;
head->next = NULL;
//采用尾插法,构建链表
//则需要构建一个链表的尾指针
Node* tail = head;
for(int i = 1; i < size ; i++)
{
Node* new = (Node*)malloc(sizeof(Node));
assert(new);
scanf("%d",&first);
new -> data = first;
tail-> next = new;
new -> next = NULL;
tail = tail->next;
}
return head;
}
//递归删除不带头节点的单链表L中所有值为x的结点
Node* digui_delete(Node* head , int x)
{
Node* p,*q;
p = head;
if(p == NULL)
return head;
else
{
//删除的话,我这里用删除赋值法来实现 so easy啦
if(p->data == x) //这个算法失误在这一个删除算法上,这样末尾元素就要特殊处理
// 但是这样又不太好做了,还是得维护一个前面节点的指针,这样写就写不好了
{
// if(p -> next == NULL)
// {
// p->data = -1; //只能暂时置为-1,证明删除了
// return head;
// }
p->data = p->next->data;
p->next = p->next->next;
digui_delete(p,x);
}
digui_delete(p->next,x);
}
return head;
}
void print_list(Node* head)
{
Node* p;
p = head;
while(p != NULL)
{
printf("%d ", p->data);
p = p->next; //我每次都爱漏掉这个
}
printf("\n");
}
int main(int argc, char const *argv[])
{
Node* list = Init_List();
list = digui_delete(list,3);
print_list(list);
return 0;
}
运行截图