双链表(Java)的添加,删除与查找

链表(Java)二

力扣:设计链表(707)

上次咱们介绍了单链表(链表(一)
(本次关于查找添加以及删除的实现也使用上次在单链表里写的接口)
下面咱们介绍一下双链表。双链表比单链表在查询方面要快得多,但是它更加复杂,它包含了 size,记录链表元素个数,和伪头伪尾。

一、节点结构:

class ListNode{
    int val;
    //指向下一个节点
    ListNode next;
    // 与单链表的节点不同
    // 指向下一个节点
    ListNode prev;
    public  ListNode(){};
    public ListNode(int val){
        this.val =val;
    }
}

双链表初始状态如下图:
在这里插入图片描述
咱们用代码表示一下:

 public DoublyLinkedList(){
        size=0;
        head=new ListNode(0);
        tail=new ListNode(0);
        head.next=tail;
        tail.prev=head;
    }

二、双链表的添加操作:

(toAdd表示当前需要插入的新节点,以插入节点的值为5作为例子
ListNode toAdd=new ListNode(5);
pred表示当前要插入的新节点的上一个节点
succ表示当前要插入的新节点的下一个节点)

  • 找到要插入节点的前驱节点(pred)和后继节点(succ)。
  • 通过改变前驱结点和后继节点的链接关系添加元素。

在这里插入图片描述

2.在这里插入图片描述
3.在这里插入图片描述
4.在这里插入图片描述
至此,新节点插入完成
代码表示如下:

ListNode toAdd = new ListNode(e);
        toAdd.prev = pred;
        toAdd.next = succ;
        pred.next = toAdd;
        succ.prev = toAdd;

三、双链表的删除操作:

  • 找到要删除节点的前驱结点(pred)和后继节点(succ)。
  • 通过改变前驱结点和后继节点的链接关系删除元素。
    1.在这里插入图片描述

在这里插入图片描述
至此,双链表的删除操作也完成啦
代码如下:

 		pred.next = succ;
        succ.prev = pred;

四、双链表的查找操作

  • 将index和size的一半进行比较,判断是从头开始寻找,还是从尾开始寻找。简而言之,哪里路径短就从哪里开始找。
    操作如下:
    1.当size为3,index为0时,通过if语句判断,从头开始查找比较快
    在这里插入图片描述
    2.当size为3,index为2时,通过if语句判断,从尾巴开始查找比较快在这里插入图片描述
    代码如下:
 		ListNode p=head;
        if(index+1<size-index) {
            for (int i = 0; i < index + 1; ++i) {
                p = p.next;
            }
        } else{
            p = tail;
            for (int i = 0; i < size - index; ++i) {
                p = p.prev;
            }
        }
        return p.val;

以上就是双链表的添加,删除与查找
全部代码如下:

/**
 * @program: testspring
 * @description: 双链表
 * @author: ErFeng_V
 * @create: 2021-05-03 23:13
 */
public class DoublyLinkedList implements MyLinkedList {

    private int size;
    private ListNode head;
    private ListNode tail;

    public DoublyLinkedList(){
        size=0;
        head=new ListNode(0);
        tail=new ListNode(0);
        head.next=tail;
        tail.prev=head;
    }
    @Override
    public void addAtHead(int e) {
        addAtIndex(0,e);
    }

    @Override
    public void addAtTail(int e) {
         addAtIndex(size,e);
    }

    @Override
    public int get(int index) {
        if(index<0 || index>=size){
            return -1;
        }
        ListNode p=head;
        if(index+1<size-index) {
            for (int i = 0; i < index + 1; ++i) {
                p = p.next;
            }
        } else{
            p = tail;
            for (int i = 0; i < size - index; ++i) {
                p = p.prev;
            }
        }
        return p.val;
    }

    @Override
    public void addAtIndex(int index, int e) {

        if (index > size) {
            return;
        }
        //根据题意,当index小于0时,则在头部插入节点。
        if (index < 0) {
            index = 0;
        }
        ListNode pred, succ;
        if (index < size - index) {
            pred = head;
            for(int i = 0; i < index; ++i) {
                pred = pred.next;
            }
            succ = pred.next;
        }
        else {
            succ = tail;
            for (int i = 0; i < size - index; ++i) {
                succ = succ.prev;
            }
            pred = succ.prev;
        }
        ++size;
        ListNode toAdd = new ListNode(e);
        toAdd.prev = pred;
        toAdd.next = succ;
        pred.next = toAdd;
        succ.prev = toAdd;
    }

    @Override
    public void deleteAtIndex(int index) {
        if (index < 0 || index >= size) {
            return;
        }
        ListNode pred, succ;
        if (index < size - index) {
            pred = head;
            for(int i = 0; i < index; ++i) {
                pred = pred.next;
            }
            succ = pred.next.next;
        }
        else {
            succ = tail;
            for (int i = 0; i < size - index - 1; ++i) {
                succ = succ.prev;
            }
            pred = succ.prev.prev;
        }
        --size;
        pred.next = succ;
        succ.prev = pred;
    }
}
class ListNode{
    int val;
    ListNode next;
    ListNode prev;
    public  ListNode(){};
    public ListNode(int val){
        this.val =val;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值