链表--双向链表(哨兵)

本文详细介绍了DoublyLinkedListSentinel类,一个使用哨兵节点的双向链表,包括findNode、insert、addFirst、remove、removeFirst、addLast和removeLast等方法,展示了如何在链表中进行元素的增删操作以及迭代遍历。
摘要由CSDN通过智能技术生成
  • 双向链表,每个元素知道其上一个元素和下一个元素

 

public class DoublyLinkedListSentinel implements Iterable<Integer> {

    private final Node head;//头哨兵
    private final Node tail;//尾哨兵

    public DoublyLinkedListSentinel() {
        head = new Node(null, 666, null);
        tail = new Node(null, 888, null);
        head.next = tail;//初始化时,头哨兵的尾是指向尾哨兵的头
        tail.prev = head;//初始化时,尾哨兵的尾是指向头哨兵的头
    }
    
	//根据index寻找节点
    private Node findNode(int index) {
        int i = -1;
        //从头哨兵开始查,结束条件是到尾哨兵时就结束
        for (Node p = head; p != tail; p = p.next, i++) {
            if (i == index) {
                return p;
            }
        }
        return null;
    }
	//在头部添加新节点
    public void addFirst(int value) {
        insert(0, value);
    }

    public void removeFirst() {
        remove(0);
    }

   //在尾部添加新节点
    public void addLast(int value){
        //获取当前尾节点的前一个节点
        Node last = tail.prev;
        //新建节点
        Node added = new Node(last, value, tail);
        last.next=added;
        tail.prev=added;
    }

    //删除最后的节点
    public void removeLast(){
        Node removed = tail.prev;
        //判断删除的是头哨兵时
        if(removed==head){
            illegalIndex(0);
        }
        Node prev = removed.prev;
        prev.next=tail;
        tail.prev=prev;

    }

   //根据index来插入节点
    public void insert(int index,int value){
        //前一节点
        Node prev = findNode(index - 1);
        //当index输入不合法
        if(prev==null){
            illegalIndex(index);
        }
        //后一节点
        Node next=prev.next;
        Node inserted = new Node(prev, value, next);
        //使得新插入的节点的值指向前一节点的尾
        prev.next=inserted;
        //使得新插入的节点的值指向后一节点的头
        next.prev=inserted;
    }

   //根据index进行删除节点操作
    public void remove(int index){
        Node prev = findNode(index - 1);
        if(prev==null){
            illegalIndex(index);
        }
        //找到需要删除的节点
        Node removed = prev.next;
        //对于删除的是尾节点,我们要进行判断
        if(removed==tail){
            illegalIndex(index);
        }
        Node next = removed.next;
        //被删除节点的前后节点进行对接
        prev.next=next;
        next.prev=prev;
    }

    private IllegalArgumentException illegalIndex(int index) {
        return new IllegalArgumentException(
                String.format("index [%d] 不合法%n", index));
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            Node p = head.next;

            @Override
            public boolean hasNext() {
                return p != tail;
            }

            @Override
            public Integer next() {
                int value = p.value;
                p = p.next;
                return value;
            }
        };
    }

    static class Node {
        Node prev;//上一节点指针
        int value;//值
        Node next;//下一个节点指针

        public Node(Node prev, int value, Node next) {
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }
}

实现:

初始化双向链表--哨兵版:

findNode方法:

对于insert、addFirst方法:

对于remove、removeFirst方法:

对于addLast方法:

对于removeLast方法:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值