- 删除节点还是要找到待删除节点的前驱节点;
- 同时取出待删除节点,作为前驱节点“跨越”自己的桥梁;
// 从链表中删除index(0-based)位置的元素, 返回删除的元素
// 在链表中不是一个常用的操作,练习用:)
public E remove(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Remove failed. Index is illegal.");
Node prev = dummyHead;
for(int i = 0 ; i < index ; i ++)
prev = prev.next;
Node retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size --;
return retNode.e;
}
// 从链表中删除第一个元素, 返回删除的元素
public E removeFirst(){
return remove(0);
}
// 从链表中删除最后一个元素, 返回删除的元素
public E removeLast(){
return remove(size - 1);
}
- 注意while循环的条件prev.next != null,链表这种数据结构不会存在两个节点之间出现一个null的情况,null只会出现在最后一个节点之后,所以当prev.next == null时,prev已经指向了最后一个节点;
- prev由dumyHead开始,走完第一次循环后指向第一个节点,所以循环标号i和prev指向的节点的索引一一对应;
// 从链表中删除元素e
public void removeElement(E e){
Node prev = dummyHead;
while(prev.next != null){
if(prev.next.e.equals(e))
break;
prev = prev.next;
}
// prev.next不是最后一个节点
if(prev.next != null){
Node delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
size --;
}
}