双向链表也称为双链表,是链表的一种,它的每个数据节点都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个节点开始,都可以很方便地访问它的前驱节点和后继节点。
双向列表的特点:
head
和 tail
分别指向头部和尾部的节点prev
data
next
第一个节点
的 pre 是 null最后一个节点
的 next 是 null双向链表在进行增加和删除元素的时候,只需要改变 prev
和 next
的指向即可完成相关的操作。
增加节点
删除节点
创建 DoubleLinkedList
类,该类中写一个内部类 Node
作为节点对象,Node
中拥有的属性是 data
、next
、prev
分别对应 所保存的数据
、下一个节点对象
、上一个节点对象
,DoubleLinkedList
链表对象所拥有的属性为 head
、tail
、size
,分别对应头节点
、尾节点
和链表长度
。
/**
* 双向链表
* @param
*/
public class DoubleLinkedList<E> {
// 头节点
private Node<E> head;
// 尾节点
private Node<E> tail;
// 长度
private int size;
public DoubleLinkedList() {
this.head = null;
this.tail = null;
this.size = 0;
}
// 内部类:节点对象
private static class Node<E> {
E data;
Node<E> next;
Node<E> prev;
// 无参构造
public Node() {
this.data = null;
this.next = null;
this.prev = null;
}
// 构造方法
public Node(Node<E> prev, E data, Node<E> next) {
this.data = data;
this.next = next;
this.prev = prev;
}
@Override
public String toString() {
return data.toString();
}
}
}
// 往链表末端添加元素
public void add(E element) {
this.add(size,element);
}
// 往指定位置添加元素
public void add(int index,E element) {
if (index > size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
Node<E> node = new Node<>();
node.data = element;
// 判断当前链表的长度是否为 0
if (size == 0) {
// 如果为 0 ,则表示当前为第一次添加元素,头节点和尾节点就是新添加的节点
head = node;
tail = node;
} else {
if (index == 0) {
// 从头端插入元素
node.next = head;
head.prev = node;
head = node;
} else if (index == size) {
// 从尾端插入元素
node.prev = tail;
tail.next = node;
tail = node;
} else {
// 从链表的间件位置插入元素
// p:表示之前在 index 位置上的节点
// q:表示之前在 index - 1 位置上的节点
Node<E> p,q;
// 遍历链表
p = head;
int count = 0;
while (p.next != null) {
if (count == index) {
break;
}
p = p.next;
count++;
}
q = p.prev;
node.prev = q;
node.next = p;
q.next = node;
p.prev = node;
}
}
size++;
}
// 删除链表末端元素
public E remove() {
return this.remove(size);
}
// 删除链表中指定元素
public E remove(E element) {
int index = indexOf(element);
if (index != -1) {
return this.remove(index);
}
return null;
}
// 删除链表中指定下标元素
public E remove(int index) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
E ret;
if (index == 0) {
// 删除头节点
ret = head.data;
Node<E> node = head.next;
head.next = null;
node.prev = null;
head = node;
} else if (index == size-1) {
// 删除尾节点
ret = tail.data;
Node<E> node = tail.prev;
tail.prev = null;
node.next = null;
tail = node;
} else {
// 删除中间位置的某个元素
// p:表示 index 位置上的节点
// q:表示 index - 1 位置上的节点
// y:表示 index + 1 位置上的节点
Node<E> p,q,y;
// 遍历链表
p = head;
int count = 0;
while (p.next != null) {
if (count == index) {
break;
}
p = p.next;
count++;
}
ret = p.data;
y = p.next;
q = p.prev;
q.next = y;
y.prev = q;
}
size--;
return ret;
}
// 获取指定元素的下标
public int indexOf(E element) {
int index = 0;
Node<E> p = head;
while (!p.data.equals(element)) {
index++;
p = p.next;
if (index >= size) {
return -1;
}
}
return index;
}
// 获取指定下标的元素
public E get(int index) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
if (index == 0) {
return head.data;
} else if (index == size-1) {
return tail.data;
} else {
Node<E> p = head;
for (int i = 0; i < index; i++) {
p = p.next;
}
return p.data;
}
}
// 设置指定下标的值
public E set(int index,E element) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
E ret;
if (index == 0) {
ret = head.data;
head.data = element;
} else if (index == size-1) {
ret = tail.data;
tail.data = element;
} else {
Node<E> p = head;
for (int i = 0; i < index; i++) {
p = p.next;
}
ret = p.data;
p.data = element;
}
return ret;
}
// 返回链表长度
public int size() {
return size;
}
// 指定元素是否在链表中存在
public boolean contains(E element) {
return indexOf(element) != -1;
}
// 当前链表是否为空链表
public boolean isEmpty() {
return size == 0;
}
// 清空链表
public void clear() {
head = null;
tail = null;
size = 0;
}
// 排序
public void sort(Comparator<E> comparator) {
if (comparator == null) {
throw new IllegalArgumentException("comparable can not null");
}
if (size == 0 || size == 1) {
return;
}
// 选则排序
Node<E> nodeA = head;
Node<E> nodeB = nodeA.next;
while (nodeA.next != tail) {
while (nodeB != tail) {
if (comparator.compare(nodeA.data,nodeB.data) > 0) {
E temp = nodeA.data;
nodeA.data = nodeB.data;
nodeB.data = temp;
}
nodeB = nodeB.next;
}
nodeA = nodeA.next;
nodeB = nodeA.next;
}
}
// 截取链表
public DoubleLinkedList<E> subList(int fromIndex,int toIndex) {
if (fromIndex < 0 || toIndex >= size || fromIndex > toIndex) {
throw new IllegalArgumentException("Illegal Index" );
}
Node<E> nodeA = head;
for (int i = 0; i < fromIndex; i++) {
nodeA = nodeA.next;
}
Node<E> nodeB = head;
for (int i = 0; i < toIndex; i++) {
nodeB = nodeB.next;
}
DoubleLinkedList<E> list = new DoubleLinkedList<>();
Node<E> p = nodeA;
while (p != nodeB) {
list.add(p.data);
p = p.next;
}
return list;
}
import java.util.Comparator;
/**
* 双向链表
* @param
*/
public class DoubleLinkedList<E> {
// 头节点
private Node<E> head;
// 尾节点
private Node<E> tail;
// 长度
private int size = 0;
public DoubleLinkedList() {
this.head = null;
this.tail = null;
this.size = 0;
}
// 内部类:节点对象
private static class Node<E> {
E data;
Node<E> next;
Node<E> prev;
// 无参构造
public Node() {
this.data = null;
this.next = null;
this.prev = null;
}
// 构造方法
public Node(Node<E> prev, E data, Node<E> next) {
this.data = data;
this.next = next;
this.prev = prev;
}
@Override
public String toString() {
return data.toString();
}
}
// 往链表末端添加元素
public void add(E element) {
this.add(size,element);
}
// 往指定位置添加元素
public void add(int index,E element) {
if (index > size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
Node<E> node = new Node<>();
node.data = element;
// 判断当前链表的长度是否为 0
if (size == 0) {
// 如果为 0 ,则表示当前为第一次添加元素,头节点和尾节点就是新添加的节点
head = node;
tail = node;
} else {
if (index == 0) {
// 从头端插入元素
node.next = head;
head.prev = node;
head = node;
} else if (index == size) {
// 从尾端插入元素
node.prev = tail;
tail.next = node;
tail = node;
} else {
// 从链表的间件位置插入元素
// p:表示之前在 index 位置上的节点
// q:表示之前在 index - 1 位置上的节点
Node<E> p,q;
// 遍历链表
p = head;
int count = 0;
while (p.next != null) {
if (count == index) {
break;
}
p = p.next;
count++;
}
q = p.prev;
node.prev = q;
node.next = p;
q.next = node;
p.prev = node;
}
}
size++;
}
// 删除链表末端元素
public E remove() {
return this.remove(size);
}
// 删除链表中指定元素
public E remove(E element) {
int index = indexOf(element);
if (index != -1) {
return this.remove(index);
}
return null;
}
// 删除链表中指定下标元素
public E remove(int index) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
E ret;
if (index == 0) {
// 删除头节点
ret = head.data;
Node<E> node = head.next;
head.next = null;
node.prev = null;
head = node;
} else if (index == size-1) {
// 删除尾节点
ret = tail.data;
Node<E> node = tail.prev;
tail.prev = null;
node.next = null;
tail = node;
} else {
// 删除中间位置的某个元素
// p:表示 index 位置上的节点
// q:表示 index - 1 位置上的节点
// y:表示 index + 1 位置上的节点
Node<E> p,q,y;
// 遍历链表
p = head;
int count = 0;
while (p.next != null) {
if (count == index) {
break;
}
p = p.next;
count++;
}
ret = p.data;
y = p.next;
q = p.prev;
q.next = y;
y.prev = q;
}
size--;
return ret;
}
// 获取指定元素的下标
public int indexOf(E element) {
int index = 0;
Node<E> p = head;
while (!p.data.equals(element)) {
index++;
p = p.next;
if (index >= size) {
return -1;
}
}
return index;
}
// 获取指定下标的元素
public E get(int index) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
if (index == 0) {
return head.data;
} else if (index == size-1) {
return tail.data;
} else {
Node<E> p = head;
for (int i = 0; i < index; i++) {
p = p.next;
}
return p.data;
}
}
// 设置指定下标的值
public E set(int index,E element) {
if (index >= size || index < 0) {
throw new IllegalArgumentException("Illegal Index:" + index);
}
E ret;
if (index == 0) {
ret = head.data;
head.data = element;
} else if (index == size-1) {
ret = tail.data;
tail.data = element;
} else {
Node<E> p = head;
for (int i = 0; i < index; i++) {
p = p.next;
}
ret = p.data;
p.data = element;
}
return ret;
}
// 返回链表长度
public int size() {
return size;
}
// 指定元素是否在链表中存在
public boolean contains(E element) {
return indexOf(element) != -1;
}
// 当前链表是否为空链表
public boolean isEmpty() {
return size == 0;
}
// 清空链表
public void clear() {
head = null;
tail = null;
size = 0;
}
// 排序
public void sort(Comparator<E> comparator) {
if (comparator == null) {
throw new IllegalArgumentException("comparable can not null");
}
if (size == 0 || size == 1) {
return;
}
// 选则排序
Node<E> nodeA = head;
Node<E> nodeB = nodeA.next;
while (nodeA.next != tail) {
while (nodeB != tail) {
if (comparator.compare(nodeA.data,nodeB.data) > 0) {
E temp = nodeA.data;
nodeA.data = nodeB.data;
nodeB.data = temp;
}
nodeB = nodeB.next;
}
nodeA = nodeA.next;
nodeB = nodeA.next;
}
}
// 截取链表
public DoubleLinkedList<E> subList(int fromIndex,int toIndex) {
if (fromIndex < 0 || toIndex >= size || fromIndex > toIndex) {
throw new IllegalArgumentException("Illegal Index" );
}
Node<E> nodeA = head;
for (int i = 0; i < fromIndex; i++) {
nodeA = nodeA.next;
}
Node<E> nodeB = head;
for (int i = 0; i < toIndex; i++) {
nodeB = nodeB.next;
}
DoubleLinkedList<E> list = new DoubleLinkedList<>();
Node<E> p = nodeA;
while (p != nodeB) {
list.add(p.data);
p = p.next;
}
return list;
}
}
public class TextDem {
public static void main(String[] args) {
DoubleLinkedList<String> list = new DoubleLinkedList<>();
// 添加元素
list.add("米大傻");
list.add("米二傻");
list.add("米三傻");
list.add("米四傻");
list.add("米五傻");
list.add(1,"米六傻");
list.add(0,"米七傻");
// 删除指定下标元素
list.remove(3);
// 查找元素下标
int index = list.indexOf("米四傻");
System.out.println("index = " + index);
// 设置指定下标的值
list.set(2,"李大霄");
// 遍历集合
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("====================");
// 截取集合
DoubleLinkedList<String> subList = list.subList(2, 5);
for (int i = 0; i < subList.size(); i++) {
System.out.println(subList.get(i));
}
System.out.println("====================");
// 清空集合
list.clear();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}