无头节点的单链表中如何删除结点

在有头结点的单链表中,删除结点的方式是,通过找到删除节点的前面一个结点,将前一个结点的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;
        }
    }