C语言单链表递归删除,王道数据结构(2.1)c语言设计一个递归算法,删除不带头结点的单链表L中全部值为x的节点(有bug)...

这道题用c语言重写的正确答案在这里html

这道题的话,亮点在递归上。既然是递归,咱们就要考虑,递归基是什么,很明显,这一题的递归基也就是当指向元素的指针,指向为NULL的时候,咱们就直接返回头节点便可c++

这道题我是这么一个思路,而后让人棘手的就是,在递归的时候如何进行删除?咱们知道在c语言的删除中是须要有这个节点的前驱的,否则的话就无法经过前驱删除。web

还有一种不须要经过前驱的删除方法,就是假设咱们要删除的是p点,咱们令算法

p -> data = p->next->data

p->next = p->next->next;

经过将其后面一个节点的值赋值给它,而后删除后一个结点便可。svg

🍓可是这有一个大大的问题,就是说,若是你要删除的元素是最后一个元素的话,就会由于指针越界而报错,目前我不知道如何来解决

课本上的答案是这样的(给的应该是一个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++也不太会,哎~ui

先挖个坑,把学习 c++ 和c语言指针的指针提上日程,等学完之后再填吧.net

代码:指针

#include

#include

#include

//递归删除不带头节点的单链表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;

}

运行截图

c1f95eb0a61d7ad697923d504fda9ac2.pngcode

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值