问题背景
没错这个又菜又爱玩的笔者又踩坑了,毫无疑问又让学长捞出来了。今天的问题在于链表这里,里面有c++的引用也有c的指针,虽然这两种语言的问题不太应该放在一起写,但是我问题是由c++衍生出c语言的基础问题(希望各位读者写程序的时候将c和c++分开分析问题,不然问题就会很麻烦)。
在关于链表的学习中,使用递归算法,删除一个不含头结点的的单链表L所有含有x的节点。
我的问题
解题代码
//递归删除元素x
void Del_xByRecursion(LinkList &L,int x)
{
LNode *p;
if(L == NULL) //如果为空,则返回
return ;
if(L->data == x) //如果L指向x,则删除当前指针
{
p = L;
L = L->next; //注意此处并没有造成短链,因为函数传递的是引用的缘故
delete p;
Del_xByRecursion(L,x);
}
else
Del_xByRecursion(L->next,x);
}
在这里我对于 L = L->next; 产生了疑惑,认为前驱节点没有将next指针指向被删除节点之后的节点,因此前驱节点在此处L释放后指向了一个NULL空间,所有产生了断链。(注意:这是错误想法!!!)
我这么想的原因是因为我没有注意LinkList &L,这之中LinkList是一个指针,对于c++的&(引用)来说相当于引用了一个指针,也就相当于c语言的二重指针。
因此,此时的L实际上是前驱节点next的地址,而不是前驱节点next的值, L = L->next; 这一段代码实际上是将前驱节点的next值改变,指向了被删除节点之后的节点。
唉,吸取教训不讲c++和c的规则混合使用,不然就出现了指针和引用弄得真真假假分不清。
最后最重要的是要有个好学长捞我!!!
感谢学长。
最后附上真确的纯c语言代码。
C语言代码实现
#include <stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLF -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
void CreateList_L(LinkList *L, int n) {
*L = (LinkList)malloc(sizeof(LNode));
(*L) -> next = NULL;
for(ElemType i = n; i > 0; i --) {
LinkList p = (LinkList)malloc(sizeof(LNode));
p -> data = i;
p -> next = (*L) -> next;
(*L) -> next = p;
}
}
//递归删除元素x
void Del_xByRecursion(LinkList *L,int x)
{
LNode *p;
if((*L) == NULL) //如果为空,则返回
return ;
if((*L)->data == x) //如果L指向x,则删除当前指针
{
p = (*L);
(*L) = (*L)->next; //注意此处并没有造成短链,因为函数传递的是引用的缘故
free(p);
Del_xByRecursion(L,x);
}
else
Del_xByRecursion(&((*L)->next),x);
}
Status pShow(LinkList L) {
if(L == NULL) {
exit(OVERFLOW);
}
printf("========== LinkList ===========\n");
ElemType i = 0;
LNode *p;
for(LNode *p = L -> next; p != NULL; p = p -> next) {
printf("index %d, %d\n", i, p -> data);
i++;
}
return OK;
}
int main()
{
LinkList L = NULL;
/* Write C code in this online editor and run it. */
CreateList_L(&L,5);
pShow(L);
Del_xByRecursion(&L,3);
pShow(L);
return 0;
}
当然了笔者比较小白,大佬喷的时候轻点((dog)hhh,狗头保命)