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
后驱指向newNode
,newNode
前驱指向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
*/