双链表的增删改查(java)

双链表

​ 双链表与单链表的区别在于双链表中除了有指向下一个节点的next,还有指向其上一个节点的pre。下面定义节点类:

//节点类,每个对象表示一个节点
class Node2 {
    int no;
    String name;
    String nickName;
    Node2 next; //指向下一个节点
    Node2 pre;  //指向前一个节点

    Node2(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "Node2{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}

将节点插入到链表尾部

  • //尾插法
    public void add(Node2 newNode){
        //使用临时节点指示链表最后一个节点位置
        Node2 tempNode = headNode;
        while (true) {
            if (tempNode.next == null) {
                break;
            }
            tempNode = tempNode.next;
        }
        //最后一个节点(tempNode)的next指向待插入节点
        tempNode.next = newNode;
        //待插入节点的pre指向tempNode
        newNode.pre = tempNode;
    }
    

将节点插入有序双链表使之仍然有序

  • 插入的位置如果是最后一个节点的后面,要注意空指针问题。

  • 使用临时变量tempNode指向插入位置的前一个节点。(也可以指向插入位置的后一个节点,代码稍微修改即可)。初始链表如下图,待插入节点P。

  • 在这里插入图片描述

  • 插入操作如下图:

  • 在这里插入图片描述

  •  //按顺序插入
    public void addByOrder(Node2 newNode){
        Node2 tempNode = headNode;
        while (tempNode.next != null){
            if (tempNode.next.no == newNode.no){
                System.out.println("节点已存在,不能插入");
                return;
            }
            if (tempNode.next.no > newNode.no){
                newNode.next = tempNode.next;
                tempNode.next.pre = newNode;
                tempNode.next = newNode;
                newNode.pre = tempNode;
                return;
            }
            tempNode = tempNode.next;
        }
        //如果插入位置在链表尾部,注意空指针异常
        tempNode.next = newNode;
        newNode.pre = tempNode;
    }
    

  • 双链表的删除可以直接找到要删除的节点(targetNode)。自我删除

  • ①将targetNode的next节点的pre指向targetNode的pre节点;

  • ②将targetNode的pre节点的next指向targetNode的next节点。

  • 这里需要注意的是如果要删除的节点是最后一个节点。那么执行①的时候会报空指针异常,因为此时targetNode的next节点是null,而null.pre就会报异常。这里需要判断要删除的节点如果是最后一个节点,就不执行①语句

  • //删除节点
    public void delete(int no){
        if (headNode.next == null){
            System.out.println("链表是空的,不能删除~~");
            return;
        }
        Node2 tempNode = headNode.next;
        while (tempNode != null){
            if (tempNode.no == no){
                //待删除节点的前一个节点的next指向待删除节点的后一个节点
                tempNode.pre.next = tempNode.next;
                //当待删除节点是最后一个节点时,其next是null,不能将null.pre指向待删除节点的前一个节点
                if (tempNode.next != null){
                    //待删除节点的下一个节点的pre指向待删除节点的前一个节点
                    tempNode.next.pre = tempNode.pre;
                }
                return;
            }
            tempNode = tempNode.next;
        }
        System.out.println("没有这个节点,不能删除哦~~");
    }
    

  • 双链表修改节点的代码与单链表修改方法一样。

  • //修改节点
    public void update(Node2 newNode){
        if (headNode.next == null){
            System.out.println("链表空的,不能修改~~");
            return;
        }
        Node2 tempNode = headNode.next;
        while (true){
            if (tempNode.no == newNode.no){
                tempNode.name = newNode.name;
                tempNode.nickName = newNode.nickName;
                break;
            }
            if (tempNode.next == null){
                System.out.println("链表中没有你要修改的节点~~");
                break;
            }
            tempNode = tempNode.next;
        }
    }
    

双链表查找节点与单链表查找方式一致

//查找节点
public void find(int no){
    if (headNode.next == null){
        System.out.println("链表是空的,不能查找~~~");
        return;
    }
    Node2 tempNode = headNode.next;
    while (tempNode != null){
        if (tempNode.no == no){
            System.out.println("no为"+no+"的节点是:"+tempNode);
            return;
        }
        tempNode = tempNode.next;
    }
    System.out.println("没有查找到这个节点~~");
}

-手动整理----如有错误欢迎指出,欢迎探讨~
-转载请注明出处

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值