1.linkedlist数据结构
1.1单项链表
private static class Node<E> {
E item;
Node<E> next;
Node(E element, Node<E> next) {
this.item = element;
this.next = next;
}
}
1.2双向链表(java中linkedlist采用双向链表实现)
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
2.核心方法的实现
2.1添加元素
原尾节点Object4的next节点为新添加的Object new
Object new的prev节点为Object4,Object new的next节点为null
2.2指定添加元素
原Object2的next节点为新添加的Object new
Object new的prev节点为Object2,Object new的next节点为Object3
原Object3的prev节点为Object new
2.3删除指定位置节点
原Object2的next节点为Object4
原Object4的prev节点为Object2
3.实现源代码
3.1源码
package com.huajie.linkedList;
import com.huajie.list.XwfList;
/**
* 手写linklist 链表集合
* @author Administrator
*
* @param <E>
*/
public class XwfLinkedList<E> implements XwfList<E> {
// 链表集合
transient int size = 0;
// 头结点
transient Node<E> first;
// 尾节点
transient Node<E> last;
public XwfLinkedList() {
}
// 链表节点
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
public int size() {
return size;
}
public void add(E e) {
// 添加第一个元素
// 创建节点
Node<E> node = new Node<E>(last, e, null);
if (first == null) {
// 给节点赋值
node.item = e;
// 给第一个node赋值
first = node;
} else {
// 添加第二个以上
// node.prev = last;
// 给节点赋值
node.item = e;
// 上一个node
last.next = node;
}
// 给最后一个node赋值
last = node;
size++;
}
public void clear() {
// for (int i = 0; i < size; i++) {
// Node<E> node = node(i);
// node.item = null;
// node.next = null;
// node.prev = null;
// }
for (Node<E> node = first; node != null;) {
Node<E> next = node.next;
node.item = null;
node.next = null;
node.prev = null;
node = next;
}
first = last = null;
size = 0;
}
// 获取元素
// jdk1.7之前 都是 从头到尾
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
// 获取脚标节点
public Node<E> node(int index) {
Node<E> node = null;
// 如果index小于size的一半 从前往找
if (index < (size >> 1)) {
node = first;
for (int i = 0; i < index; i++) {
node = node.next;
}
} else {
node = last;
for (int i = size - 1; i > index; i--) {
node = node.prev;
}
}
return node;
}
// 在指定脚标添加节点
public void add(int index, E element) {
checkElementIndex(index);
if (index == size) {
add(element);
} else {
// 获取index节点
final Node<E> nodeIndex = node(index);
// 这个节点的next为
final Node<E> nodeNext = nodeIndex.next;
// 创建节点
Node<E> nodeCurrent = new Node<E>(nodeIndex, element, nodeNext);
nodeIndex.next = nodeCurrent;
nodeNext.prev = nodeCurrent;
}
size++;
}
// 删除节点
public E remove(int index) {
checkElementIndex(index);
// 获取index节点
Node<E> node = node(index);
final E element = node.item;
final Node<E> next = node.next;
final Node<E> prev = node.prev;
// 上一个节点的下一个节点设置为当前index节点的下一个节点
if (prev != null) {
prev.next = next;
node.prev = null;
} else {
first = next;
}
// 下一个节点的上一个节点设置为当前index节点的上一个节点
if (next != null) {
next.prev = prev;
node.next = null;
} else {
last = prev;
// prev.next = null;
}
// 当前节点设置为空
node.item = null;
size--;
return element;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + size;
}
public boolean remove(Object o) {
// 有兴趣可以实现
return false;
}
}
3.2jdk源码对比
add(E e),实现原理基本一致,在链表的最后进行添加
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
add(index,E e)方法
看方法名是在Before之前,继续往下看源码,确实是插入在该位置元素的前面
4.测试
package com.huajie.linkedList;
import com.huajie.list.XwfList;
public class Test001 {
public static void main(String[] args) {
XwfList<String> a = new XwfLinkedList<String>();
a.add("haha1");
a.add("haha2");
a.add("haha3");
a.add("haha4");
for (int i = 0; i < a.size(); i++) {
System.out.println(a.get(i));
}
System.out.println("==================");
// a.remove(3);
// for (int i = 0; i < a.size(); i++) {
// System.out.println(a.get(i));
// }
System.out.println("==================");
a.add(1,"555");
for (int i = 0; i < a.size(); i++) {
System.out.println(a.get(i));
}
}
}