双向循环链表
图解以及伪代码
这里就不跟大家文字讲解了,我觉得通过看图解和代码的分析会使你的影响更加深刻!!(掩饰我的“懒”)!!!
循序列表
add方法
get方法
remove方法
重载add方法
代码实现
package list;
/**
* 这是一个双向循环链表
*/
public class LinkedList<E> {
//head用于存放头节点的地址。
private Node head;
//size用于存放链表的长度。
private int size;
/*
Node类用来描述链表中的一个节点,
其中,data用于存放数据(元素),
next和prev分别存放前驱和后继节点的地址。
*/
class Node{
E data;
Node next;
Node prev;
Node(E e){
data = e;
}
}
/**
* 将元素添加到链表的末尾。
* @param e 要添加的元素。
* @return 添加成功,返回true。
*/
public boolean add(E e){
//将元素封装成一个节点
Node node = new Node(e);
//如果链表为空,则新节点成为头节点
if(head == null){
head = node;
head.next = head;
head.prev = head;
//将链表的长度加1
size ++;
return true;
}
//找到尾节点
Node last = head.prev;
//将新节点添加到尾节点后面
last.next = node;
node.next = head;
head.prev = node;
node.prev = last;
size ++;
return true;
}
@Override
public String toString() {
if(head == null){
return "[]";
}
StringBuilder sb = new StringBuilder("[");
sb.append(head.data);
Node node = head.next;
while(node != head){
sb.append("," + node.data);
node = node.next;
}
return sb.append("]").toString();
}
/**
*
* 返回链表的长度
*/
public int size(){
return size;
}
/**
* 返回指定下标处的某个元素
* @param index 下标
* @return 返回的元素
*/
public E get(int index){
if(index < 0 || index >= size){
throw new IndexOutOfBoundsException("下标越界");
}
Node node = getNode(index);
return node.data;
}
/*
依据下标找到某个节点
*/
private Node getNode(int index) {
Node node = head;
if(index < size >> 1){
for(int i = 0; i < index; i ++){
node = node.next;
}
}else{
for(int i = size; i > index; i --){
node = node.prev;
}
}
return node;
}
/**
* 删除指定位置的元素。
* @param index 位置
* @return 被删除的元素
*/
public E remove(int index){
if(index < 0 || index >= size){
throw new IndexOutOfBoundsException("下标越界");
}
//如果链表的长度为1,则删除该节点之后,需要将head置为null。
if(size == 1){
E e = head.data;
head = null;
size --;
return e;
}
//找到要删除的节点
Node node = getNode(index);
//找到该节点的前驱和后继节点
Node prev = node.prev;
Node next = node.next;
//让前驱和后继节点之间建立引用关系
next.prev = prev;
prev.next = next;
if(index == 0){
head = next;
}
size --;
return node.data;
}
/**
* 将元素插入到指定的位置
* @param index 位置
* @param e 要插入的元素
*/
public void add(int index,E e){
if(index < 0 || index > size)
throw new IndexOutOfBoundsException("下标越界");
if(index == size){
add(e);
return;
}
Node node = new Node(e);
Node next = getNode(index);
Node prev = next.prev;
prev.next = node;
node.next = next;
next.prev = node;
node.prev = prev;
if(index == 0){
head = node;
}
size ++;
}
}