废话不多说,直接上代码。
package cn.tedu.datastruct;
public class LinkedList<E> {
/*
head保存链表头节点的引用
*/
private Node head;
private int size;
/**
* Node用来描述一个节点,
* 其中E用来存放数据,
* prev存放前驱节点的引用,
* next存放后继节点的引用
*/
private class Node {
E data;
Node prev;
Node next;
public Node(E e) {
this.data = e;
}
}
/**
* 将元素添加到链表的末尾
*
* @param e 待添加的元素
* @return 添加成功返回true
*/
public boolean add(E e) {
if (head == null) {
//链表为空,则当前新添加的节点为头节点
head = new Node(e);
head.prev = head;
head.next = head;
size++;
return true;
}
/*
如果链表不为空,则先找到尾节点,然后重新建立节点的引用关系
*/
//找到尾节点
Node last = head.prev;
//重新建立节点的引用关系
Node node = new Node(e);
last.next = node;
node.next = head;
head.prev = node;
node.prev = last;
size++;
return true;
}
/**
* 在指定下标处添加新元素
*
* @param index 下标
* @param element 新元素
*/
public void add(int index, E element) {
//判断下标的取值
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("下标越界");
}
//如果添加的下标等于size,即向末尾追加
if (index == size) {
add(element);
return;
}
//得到指定下标的源节点
Node node = getByIndex(index);
//创建新节点
Node newNode = new Node(element);
//得到前一个节点
Node prev = node.prev;
//重新建立引用关系
prev.next = newNode;
newNode.next = node;
node.prev = newNode;
newNode.prev = prev;
//如果添加的下标是0,则这个新节点为头结点
if (index == 0) {
head = newNode;
}
size++;
}
/**
* 获得链表长度
* @return 链表的长度
*/
public int size() {
return size;
}
/**
* 返回指定下标的某个元素
*
* @param index 下标
* @return 对应下标的某个元素
*/
public E get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("下标越界");
}
return getByIndex(index).data;
}
/**
* 删除指定下标的元素
*
* @param index 下标
* @return 被删除的元素
*/
public E remove(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("下标越界");
}
if (size == 1) {
//只有一个节点
E data = head.data;
head = null;
size--;
return data;
}
//获取被删除的节点
Node node = getByIndex(index);
//被删除节点的前一个节点
Node prev = node.prev;
//被删除节点的下一个节点
Node next = node.next;
//重新建立引用关系
prev.next = next;
next.prev = prev;
//如果删除的是第一个节点,应该让第二个节点充当头节点
if (index == 0) {
head = node.next;
}
//链表的长度减1
size--;
//返回被删除的元素
return node.data;
}
/**
* 返回链表中各个元素的值,如果链表为空,返回"[]",否则,各个元素值使用","分隔
*
* @return
*/
@Override
public String toString() {
if (head == null) {
return "[]";
}
Node next = head.next;
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("[" + head.data);
/*
开始进行遍历,直到下一个节点是头节点,则循环结束
*/
while (next != head) {
stringBuffer.append(", " + next.data);
next = next.next;
}
stringBuffer.append("]");
return stringBuffer.toString();
}
/**
* 返回执行下标的节点
*
* @param index 下标
* @return 对应下标的节点
*/
private Node getByIndex(int index) {
Node node = head;
if (index <= size / 2) {
for (int i = 0; i < index; i++) {
node = node.next;
}
} else {
for (int i = 0; i < size - index; i++) {
node = node.prev;
}
}
return node;
}
}
网友评论