无头节点的单链表中如何删除结点
在有头结点的单链表中,删除结点的方式是,通过找到删除节点的前面一个结点,将前一个结点的next指向删除结点的next
pre->next = cur.next;
pre 可以预设为 head(头结点),比较 pre.next 和待删除的结点,当 pre.next==delNode时,就找到了待删除结点的前一个结点,然后执行上述赋值操作
但是在没有头节点,只有头指针的单链表中,假如待删除的结点是第一个结点,只能从第一个结点开始遍历,就无法通过找到前一个结点进行赋值操作。
这里我删除结点的思路是:
- 如果删除节点是第一个结点并且下一个结点不为空、或者是中间结点
将下一个节点的内容赋值到当前删除结点 - 如果删除的结点是第一个节点,并且链表只有这一个结点,则使head=null
- 如果删除的结点是尾结点,则遍历链表找到前一个结点,将这个结点的next赋值为空
代码实现(不借助其他结点)
public void delEmpById(int id) {
if (head == null) {
System.out.println("链表为空");
return;
}
Emp cur = head;
while (cur != null && cur.id != id) {
cur = cur.next;
}
if (cur == null) {
//没有找到待删除结点
System.out.println("未找到要删除的结点");
return;
} else {
//找到了待删除的结点
if (cur == head & head.next == null) {//要删除的结点是第一个结点,并且链表中只有一个结点
head = null;
} else if (cur.next == null) {//该结点是尾结点
Emp temp = head;
while(temp.next!=cur){
temp = temp.next;
}
temp.next=null;
} else {//该结点是中间结点或者头结点
//将下一个结点的数据拷贝到当前结点,然后将下一个结点赋为null
cur.id = cur.next.id;
cur.name = cur.next.name;
cur.next = cur.next.next;
}
}
}
除此之外,也可以构建一个头结点,该头节点指向head,然后创建一个辅助的遍历结点cur,指向自己构建的头节点
从该结点开始遍历
- 如果删除的结点是第一个结点,则使head = head.next
- 如果删除的结点是中间结点或者尾结点,则使cur.next = cur.next.next
- 如果cur.next==null,说明链表中没有该结点
代码实现(借助额外构建的头结点)
public void delEmpById(int id) {
if (head == null) {
System.out.println("链表为空");
return;
}
//创建一个新的头节点,next指向链表的第一个结点
Emp newHead = new Emp(0, "");
newHead.next = head;
//从这个新结点开始遍历
Emp cur = newHead;
while (cur.next != null && cur.next.id != id) {
cur = cur.next;
}
if(cur.next==null){
System.out.println("未找到该结点");
return;
}else if (cur.next == head) {
head = head.next;
} else {
//删除的是中间结点或者尾结点
cur.next = cur.next.next;
}
}