- update on 20200506:注明本文使用的是头结点方法;修改相关格式;
1.错误代码
(1)删除值为x的节点
//在带头结点的单链表L中,删除值为x的节点
void deleteSpecialData(Node* &L,int x) {
while(L->next!=NULL){//当没有到达链表尾部的时候,继续循环
if(L->next->data == x){
Node* q;//申请一个指针q
q=L->next;//保存L->next的指针位置
L->next = L->next->next;//改变链表的指针
delete(q);//释放节点空间q
}
else
L= L->next;//往下循环
}
}
(2)遍历输出单链表L
//遍历输出单链表
void traverseLinkList(Node* L){
L = L->next;//切换到头节点
while(L!=NULL){//如果指针不为空
printf("%d ",L->data);
L = L->next;//循环
}
}
2.结果
(1)我们什么也看不到????
3.错误总结
(1)我们在对单链表L进行查找值,删除节点的时候,不能使用头结点指针L作为循环条件,因为在函数中对L进行遍历,所以到最后,L->next==NULL,紧接着,我们又要对链表L进行遍历输出,这个时候,恰好因为L->next == NULL ,故输出为空
(2)即链表中删除特定值操作不能以链表头指针L作为循环变量。类似,我们也可以知道,在其它操作中,我们都应该避免使用L指针作为循环变量。
4.正确代码
void deleteSpecialData(Node* &L,int x) {
Node* r;
r = L;
while(r->next!=NULL){//当没有到达链表尾部的时候,继续循环
if(r->next->data == x){
Node* q;//申请一个指针q
q=r->next;//保存L->next的指针位置
r->next = r->next->next;//改变链表的指针
delete(q);//释放节点空间q
}
else
r= r->next;//往下循环
}
}
5.总结
当我们需要删除单链表中某个值的时候,请记住以下几点:
- (1)本文使用头结点方便统一操作。所谓头结点就是一个“不正规”的节点,它不存储真正的数据。只是为了方便统一操作。
- (2)我们删除节点A,必须找到结点A的前一个结点,然后修改起后继结点,所以循环里用的是r->next->data,这里的r指的得是当前的判断结点。同样,所以while()循环中也是r->next!=NULL