无头双向链表的结构:
代码分析
节点结构
class Node {
private int data;
private Node next;
private Node prev;
public Node(int data) {
this.data = data;
this.prev = null;
this.next = null;
}
}
private Node head; // 头节点
private Node last; // 尾节点
public DoubleLinked() {
this.head = null;
this.last = null;
}
1. 头插法
/**
* 1.头插法
* @param data
*/
public void addFirst(int data) {
Node node = new Node(data);
if (this.head == null) {
this.head = node;
this.last = node;
} else {
node.next = this.head;
this.head.prev = node;
this.head = node;
}
}
先判断链表是否为空,若为空,则直接插入,头节点和尾节点都直接指向新插入的元素;
若链表不为空,则把要插入节点的 next 指向链表头节点,头节点的 prev 指向新插入的节点,最后更新头节点为新插入节点,插入过程如下图所示:
2. 尾插法
/**
* 2.尾插法
* @param data
*/
public void addLast(int data) {
Node node = new Node(data);
if (this.head == null) {
this.head = node;
this.last = node;
} else {
this.last.next = node;
node.prev = this.last;
this.last = node;
}
}
若链表为空,同头插法;
若链表不为空,则把链表尾节点的 next 指向要插入节点,要插入节点的 prev 指向链表尾节点,最后更新尾节点为新插入节点,插入过程如下图所示:
3. 查找是否包含关键字 key 在单链表中
// 查找
private Node searchIndex(int index) {
checkIndex(index);
int count = 0;
Node cur = this.head;
while (count != index) {
cur = cur.next;
count++;
}
return cur;
}
// 合法性检查
private void checkIndex(int index) {
if (index < 0 || index > getLength()) {
throw new IndexOutOfBoundsException("下标不合法!");
}
}
/**
* 3.任意位置插入,第一个数据节点为0号下标
* @param index 插入位置
* @param data 插入的值
* @return true/false
*/
@Override
public boolean addIndex(int index, int data) {
if (index ==0) {
addFirst(data);
return true;
}
if (index == getLength()) {
addLast(data);
return true;
}
// cur 指向index位置的节点
Node cur = searchIndex(index);
Node node =