这里是节选的我看完课程后自己再写一次的双链表里面的删除结点的一段代码
int delete_node(dlnode *pHeader,int data)
{
dlnode *p = pHeader;
if(NULL == p)
{
return -1;
}
while(NULL != p->pNext)
{
p = p->pNext;
if(p->data == data)
{
if (NULL == p->pNext)
{
// 尾节点
// p表示当前节点地址,p->pNext表示后一个节点地址,p->pPrev表示前一个节点的地址
p->pPrev->pNext = NULL;
//p->pPrev = NULL; 可以省略,因为后面整个都被销毁了
// 销毁p节点
//free(p);
}
else
{
p->pPrev->pNext = p->pNext ;//把被删除的结点的前结点的pNext与后结点连起来
p->pNext->pPrev = p->pPrev; //把被删除的结点的后结点的pPrev与前结点连起来
//p->pPrev = NULL;
//p->pNext = NULL;
}
free(p);
return 0;
}
}
printf("未找到该结点\n");
return -1;
}
目前这段代码运行是正常的,已经找过课程代码对比修改过了
说说问题所在吧
1.我之前想的时候没有注意把这个函数写成一个有返回值的函数,写成了void类型,当然,那时候我也没有写return。但是想起课程里面说如果传进来的头结点是一个NULL的话那就会报错了,因为NULL的pNext是没有分配到的。所以在前面加上一个if来判断是否是NULL。
这里if判断之后可以不加return的,但是如果要判定正确0错误-1这样的话最好就加上return 0 return -1,网上查过0代表正确-1代表有误(大概这样吧)如果有返回值的话函数的返回值类型就得写成相应的类型,不能是void了,这里的话就是int类型。
2.可能是没有连贯着写这段代码的原因吧,我没注意到我最后main函数里面的是前插,比如说前插顺序是33 2 1,向后遍历出来的就是1 2 33了,所以当我删除的33的时候我还以为是删除的第一个结点,运行的时候出现了段错误,其实并不是这样,我删除的33是最后一个结点,即尾结点,这时候我的while循环里面是没有判断是否为尾结点这一个判断条件的,因为不加上的话,尾结点的pNext就是NULL了,不存在后面的->pPrev了,所以编译虽然没错,但是运行起来就会出现段错误。后面我从课程代码里面吧这个if判断尾结点的拉过来了,然后就没出现段错误了。
总结一下:
大体的思路还算是清晰的,起码删掉结点之后要怎么连接前后结点这些还是没问题的,但是前面的判断头结点是否为NULL,或者尾结点的判断,这些尽管在看课程的时候是懂的,但是过后自己再写一次的时候就没有注意到,可能当时的印象不深刻吧。通过这次自己再写一次之后印象深刻了很多,对很多的基础知识也得到了运用。
继续加油!