双向链表实现

1.1 基本介绍

1、单向链表优缺点

  • 单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。
  • 单向链表不能自我删除,需要靠辅助节点 ,而双向链表则可以自我删除。

2、双向链表基本介绍

双向链表也叫双向表,是链表的一种,它由多个结点组成,每个结点都由一个数据域和两个指针域组成,数据域(data)用来存储数据其中一个指针域(next)用来指向其后继结点,另一个指针域用来指向前驱结点(prev指针)。链表的头结点的数据域不存储数据,指向前驱结点的指针域值为null,指向后继结点的指针域指向第一个真正存储数据的结点。

1.2 添加操作

1、思路分析

头部插入

  • 新建插入节点newNode

  • first前驱指向newNode

  • newNode后驱指向first

  • first指向newNode,这时候head只是表示第二个节点,而head需要表示第一个节点故改变指向。

尾部插入

  • 新建插入节点newNode
  • newNode前驱指向last
  • last后驱指向newNode
  • last指向newNode,这时候last只是表示倒数第二个节点,而last需要表示最后节点故指向newNode

中间插入

新建插入节点newNode

找到要插入newNode的前一个节点preNode。和后一个节点nextNode

newNode后驱指向nextNode,nextNode前驱指向newNode,此时newNode和后面与链表已经联立,但是和前面处理分离状态。

preNode后驱指向newNodenewNode前驱指向preNode,此时插入完整操作完毕。

2、代码示例

链表类:DoubleLinkedList

package cn.linkedlist.demo03;

public class DoubleLinkedList<E> {
   
    // 链表元素的数量
    private int size;
    // 声明头结点
    private Node first;
    // 声明尾节点
    private Node last;

    // 创建Node节点
    private class Node{
   
        // 存放内容
        public E data;
        // 指向链表的上一个节点
        public Node prev;
        // 指向下一个节点
        public Node next;
        // 构造方法
        
        public Node() {
   
            
        }
        
        public Node(Node prev, E data, Node next) {
   
            this.prev = prev;
            this.data = data;
            this.next = next;
        }

        @Override
        public String toString(){
   
            return data.toString();
        }
    }

    // 初始化头结点
    public DoubleLinkedList(){
   
        first = null;
        last = null;
        size = 0;
    }

    /***
     * 获取链表中的元素个数
     * @return
     */
    public int getSize(){
   
        return size;
    }

    /***
     * 返回链表是否为空
     * @return
     */
    public boolean isEmpty(){
   
        return size == 0;
    }

    /***
     * 根据链表的index位置添加新的元素e
     * @param index
     * @param data
     */
    public void add(int index, E data){
   
        // 调用方法
        rangeCheckAdd(index);

        if (index == size) {
    // 往最后面添加元素
            addLast(data);
        } else if(index == 0){
   
            addLast(data);
        } else {
   
            // 新添加节点下一个元素
            Node nextNode = node(index);
            // 新添加节点的上一个元素
            Node prevNode = nextNode.prev;
            // 新添加节点
            Node newNode = new Node (prevNode, data, nextNode);
            // next节点的上一个prev指向新节点
            nextNode.prev = newNode;
            // prevNode节点的下一个next指向新节点
            prevNode.next = newNode;
        }
        size++;
    }

    /***
     * 在链表头添加新的元素e
     * @param data
     */
    public void addFirst(E data){
   
        // 创建一个新节点
       Node newNode = new Node(null, data, null);
       if(isEmpty()){
   
           last = newNode; // last -> newNode
       }else {
   
           first.prev = newNode; // first.prev->newNode
       }
       newNode.next = first; // newNode.next -> first;
       first = newNode;
       size++;
    }

    /***
     * 在链表末尾添加新的元素e
     * @param data
     */
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值