定义 cur 从表的第二个结点开始遍历。
定义 prev 从表的 cur 的前驱位置开始遍历。
比较此时 cur 指向结点的值是不是要删除结点的值。
是就改指向删除,不是就 cur 往后面找。
现在要删除的是,值是2的结点。
cur 此时指向了要删除的结点,进行改指向删除。
可以看到第一个节点直接指向了第三个节点。
cur 指向下一个,prev 指向 cur 的前驱。
第一个节点存的是第三个节点的地址,也就与第二个结点断开了。
prev 此时不需要移动即是 cur 的前驱。
比较此时 cur 指向结点的值是不是要删除结点的值。
是就改指向删除,不是就 cur 往后面找。
比较此时 cur 指向结点的值是不是要删除结点的。
此时的第一个结点的地址域存的是最后一个结点的地址,也就指向了它。
cur 往后走,prev 指向cur的前驱。
此时 cur 指向结点的值不是要删除的结点,cur指向下一个结点。
此时 cur 为空 遍历结束,跳出循环。所有的要删除的结点都已删除完毕。
如果头结点是要删除的结点,若按照上面的方法删除;
遍历结束后,头结点是未删除的。
可以看到此时 cur 为空了,但是还有一个结点未删除。
解决办法:
判断一下头结点是不是要删除的结点。
判断方法:
删除后:
//链表中可能是空的
if(this.head == null) {
return;
}
ListNode cur = this.head.next;//cur指向要删除的结点
ListNode prev = this.head;//prev指向要删除结点的前驱
prev.next = cur.next;//要删除结点的前驱的地址域指向key结点的后驱的地址域
cur = cur.next;//要删除的结点指向它的后驱
if (this.head.value == key) {
this.head = this.head.next;//将这个头结点指向它的后驱 - 然后就删除了
}
//删除所有key的结点
public void removeAllKey(int key) {
//链表中可能是空的
if(this.head == null) {
return;
}
ListNode cur = this.head.next;//cur指向要删除的结点
ListNode prev = this.head;//prev指向要删除结点的前驱
//cur不等于空则说明cur未找到尾结点,移动要继续
while (cur != null) {
//如果当前的cur指向的数据是我要找的key
if (cur.value == key) {
//改变指向删除
prev.next = cur.next;//要删除结点的前驱的地址域指向key结点的后驱的地址域
cur = cur.next;//要删除的结点指向它的后驱
}else{ //若不是要找的 - 跳到下一个结点
prev = cur;//当前cur结点的前驱指向cur指向的结点
cur = cur.next;//当前cur结点指向它的后驱
}
}
//如果链表的第一个结点是key
if (this.head.value == key) {
this.head = this.head.next;//将这个头结点指向它的后驱 - 然后就删除了
}
}
释放单链表中每一个结点的对象,直接置为空即可。
代码演示:
public void clear() {
this.head = null;//将的结点置为空
}