之前我有写过这个的答案,但是当时真的是太naive,无知者无畏啊,我竟然因为此来怀疑c语言对链表不能实行递归,归结原因是我对递归了解的不够透彻,今天重新学习了一下递归,也就重新编写了一下代码。
同时这也是leetcode上面203题的答案(当然用递归的话,时间复杂度会高,所以时间会长一点,如果用迭代的话会好很多)
主要思路是这张图(图来源于这个课程)
delete_x.h
#ifndef _DELETE_H_
#define _DELETE_H_
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//递归删除不带头节点的单链表L中所有值为x的结点
typedef struct Node
{
int val;
struct Node* next;
}ListNode;
//创建一个不带头节点的链表 返回链表的头指针
ListNode* Init_List()
{
ListNode* head = (ListNode*)malloc(sizeof(ListNode));
assert(head);
int first,size;
printf("please enter list sizes: ");
scanf("%d",&size);
printf("please enter list elements: ");
scanf("%d",&first);
head->val = first;
head->next = NULL;
//采用尾插法,构建链表
//则需要构建一个链表的尾指针
ListNode* tail = head;
for(int i = 1; i < size ; i++)
{
ListNode* new = (ListNode*)malloc(sizeof(ListNode));
assert(new);
scanf("%d",&first);
new -> val = first;
tail-> next = new;
new -> next = NULL;
tail = tail->next;
}
return head;
}
void print_list(ListNode* head)
{
ListNode* p;
p = head;
while(p != NULL)
{
printf("%d ", p->val);
p = p->next;
}
printf("\n");
}
ListNode* removeElements(ListNode* head, int val){
if(head == NULL)
return NULL;
ListNode* last = removeElements(head->next,val);
if(head->val == val)
return last;
else
{
head->next = last;
return head;
}
}
#endif
delete_x.c
#include"delete_x.h"
int main(int argc, char const *argv[])
{
int number ;
ListNode* head = Init_List();
printf("please enter the number you want to delete: ");
scanf("%d",&number);
head = removeElements(head,number);
print_list(head);
return 0;
}
测试截图: