单链表插入删除操作详解(引入虚拟头结点)

我们发现在解决单链表问题的时候发现在增加和删除的时候总是要单独考虑链表中头结点,再解决其他中间位置的结点,那我们可以引入一个虚拟的头结点,这样无论链表中有没有结点都是一样的解决方法。
画图来看一下引入虚拟头结点后链表的操作过程
插入
在这里插入图片描述
在头结点插入
在这里插入图片描述
我们发现引入虚拟头结点后在头部插入结点和在中间任意位置插入结点的操作都是一样的

删除任意结点
在这里插入图片描述
删除头结点
在这里插入图片描述
引入虚拟头结点后的删除操作也是一样的,不需要单独对头结点的操作进行考虑

代码实现操作过程

class Node{
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
    }
}
public class SingleLinkedListDummy {
    private int size;
    //虚拟头结点,将它的值设置为单链表不会存在的值
    private Node dummyHead= new Node(-1);

    /**
     * 任意位置插
     * @param index
     * @param data
     */
    public void addIndex(int index,int data){
        if(index < 0 || index > size)
        {
            System.out.println("index illegal");
            return;
        }
        //前驱结点从虚拟头结点开始
        Node prev=dummyHead;
        for (int i = 0; i < index; i++) {
            prev=prev.next;
        }
        Node node=new Node(data);
        node.next=prev.next;
        prev.next=node;
        size++;
    }

    /**
     * 头插
     * @param data
     */
    public void addFirst(int data){
        addIndex(0,data);
    }

    /**
     * 尾插
     * @param data
     */
    public void addLast(int data){
        addIndex(size,data);
    }

    /**
     * 删除指定索引的节点
     * @param index
     */
    public void removeIndex(int index){
        //判断index的合法性
        if(index < 0 || index >size-1)
        {
            System.out.println("index illegal!");
            return;
        }
        //前驱结点从虚拟头结点开始
        Node prev = dummyHead;
        for (int i = 0; i < index; i++) {
            prev=prev.next;
        }
        Node node=prev.next;
        prev.next=node.next;
        node.next=null;
        size--;
    }

    /**
     * 删除所有的data结点
     * @param data
     */
    public void removeData(int data){
        //前驱结点从虚拟头结点开始
        Node prev= dummyHead;
        //前驱结点的下一个一定不能为空
        while(prev.next != null)
        {
            //如果连续几个结点都是待删除的节点就一直删除
            //不需要将前驱结点向后移动
            if(prev.next.data==data)
            {
                Node node=prev.next;
                prev.next=node.next;
                node.next=null;
                size--;
            }
            //当下一个节点不是待删除结点的时候再将前驱结点向后移动
            else
            {
                prev=prev.next;
            }
        }
    }

    @Override
    public String toString() {
        String ret="";
        Node prev=dummyHead;
        while(prev.next!=null)
        {
            ret+=prev.next.data+"->";
            prev=prev.next;
        }
        ret+="NULL";
        return ret;
    }

    public static void main(String[] args) {
        SingleLinkedListDummy singleLinkedListDummy=new SingleLinkedListDummy();
        singleLinkedListDummy.addFirst(5);
        singleLinkedListDummy.addFirst(1);
        singleLinkedListDummy.addLast(5);
        singleLinkedListDummy.addLast(5);
        singleLinkedListDummy.addFirst(2);
        singleLinkedListDummy.addLast(3);
        singleLinkedListDummy.addFirst(5);
        singleLinkedListDummy.addLast(5);
        singleLinkedListDummy.addLast(5);
        singleLinkedListDummy.addLast(5);
        singleLinkedListDummy.addIndex(0,7);
        singleLinkedListDummy.addIndex(0,5);
        singleLinkedListDummy.addIndex(0,5);
        singleLinkedListDummy.addIndex(0,5);
        singleLinkedListDummy.addLast(5);
        System.out.println(singleLinkedListDummy);
        singleLinkedListDummy.removeIndex(4);
        System.out.println(singleLinkedListDummy);
        singleLinkedListDummy.removeData(5);
        System.out.println(singleLinkedListDummy);
    }
}

运行结果
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值