恋上数据结构 双向链表(JDK-LinkedList底层)
Posted 结构化思维wz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了恋上数据结构 双向链表(JDK-LinkedList底层)相关的知识,希望对你有一定的参考价值。
三、LinkedList(双向链表)
JDK中LinkedList就是用双向链表实现的
实现双向链表
package 链式结构.BidirectionalLinkedList;
/**
* @ClassName: BidirectionalLinkedList
* @Description: 双向链表(仅有与单向链表不同的代码部分)
* @author: wangz48
* @date: 2021-12-28 14:07
*/
public class BidirectionalLinkedList<E>
/*==============成员变量================*/
static final int ELEMENT_NOT_FOUND = -1;
/**
* 链表长度
*/
private int size;
private Node<E> first;
private Node<E> last;
private static class Node<E>
E element;
Node<E> prev;
Node<E> next;
public Node(Node<E> prev, E element, Node<E> next)
this.prev = prev;
this.element = element;
this.next = next;
@Override
public String toString()
StringBuilder sb = new StringBuilder();
if (prev != null)
sb.append(prev.element);
else
sb.append("null");
sb.append("_").append(element).append("_");
if (next != null)
sb.append(next.element);
else
sb.append("null");
return sb.toString();
public void clear()
size = 0;
first = null;
last = null;
public E get(int index)
return node(index).element;
public E set(int index, E element)
Node<E> node = node(index);
E old = node.element;
node.element = element;
return old;
public void add(int index, E element)
rangeCheckForAdd(index);
// size == 0
// index == 0
if (index == size) // 往最后面添加元素
Node<E> oldLast = last;
last = new Node<>(oldLast, element, null);
if (oldLast == null) // 这是链表添加的第一个元素
first = last;
else
oldLast.next = last;
else
Node<E> next = node(index);
Node<E> prev = next.prev;
Node<E> node = new Node<>(prev, element, next);
next.prev = node;
if (prev == null) // index == 0
first = node;
else
prev.next = node;
size++;
public E remove(int index)
rangeCheck(index);
Node<E> node = node(index);
Node<E> prev = node.prev;
Node<E> next = node.next;
if (prev == null) // index == 0
first = next;
else
prev.next = next;
if (next == null) // index == size - 1
last = prev;
else
next.prev = prev;
size--;
return node.element;
public int indexOf(E element)
if (element == null)
Node<E> node = first;
for (int i = 0; i < size; i++)
if (node.element == null) return i;
node = node.next;
else
Node<E> node = first;
for (int i = 0; i < size; i++)
if (element.equals(node.element)) return i;
node = node.next;
return ELEMENT_NOT_FOUND;
/**
* 获取index位置对应的节点对象
* @param index
* @return
*/
private Node<E> node(int index)
rangeCheck(index);
if (index < (size >> 1))
Node<E> node = first;
for (int i = 0; i < index; i++)
node = node.next;
return node;
else
Node<E> node = last;
for (int i = size - 1; i > index; i--)
node = node.prev;
return node;
@Override
public String toString()
StringBuilder string = new StringBuilder();
string.append("size=").append(size).append(", [");
Node<E> node = first;
for (int i = 0; i < size; i++)
if (i != 0)
string.append(", ");
string.append(node);
node = node.next;
string.append("]");
return string.toString();
/*===============其他方法===============*/
/**
* 边界检查
*/
private void outOfBounds(int index)
throw new IndexOutOfBoundsException("Index"+index+",Size:"+size);
/**
* 权限检查
*/
private void rangeCheck(int index)
if (index < 0 || index >= size)
outOfBounds(index);
/**
* add检查索引越界
*/
private void rangeCheckForAdd(int index)
if (index < 0 || index > size)
outOfBounds(index);
总结:双向链表对于单向链表操作数量缩减了一半。
对比动态数组:
- 动态数组:开辟、销毁内存空间的次数相对较少,但可能造成内存空间的浪费。(可以通过缩容解决)
- 双向链表:开辟、销毁内存空间的操作次数相对较多,但不会造成内存空间的浪费。
源码分析
四、循环链表
实现单向循环列表
与单向链表的不同: 添加、删除操作需要维护最后一个节点。
if(index == 0)
first = new Node<>(element,first);
//最后一个节点
Node<E> last = (size == 0) ? first : node(size -1);
last.next = first;
双向循环链表
以上是关于恋上数据结构 双向链表(JDK-LinkedList底层)的主要内容,如果未能解决你的问题,请参考以下文章