我们都见过火车,车厢是一节接着一节,使用多少节车厢是根据货物数量而定,而单链表结构就像火车一样,实体的单向链表就是把火车头去掉,因为火车头不能拉东西.
火车头-1>车厢0>车厢1>车厢2>车厢3>车厢4>车厢5。
那怎么在某节车厢前面或者后面新加一节车厢呢?
那么我们就要,让火车头指向新加入的车厢,再让新加入的车厢指向车厢0。想要在后面新加入一节车厢,那就让车厢5指向新的车厢。
那怎么在车厢之间新加入车厢呢?
比如对车厢2来说,让车厢2指向新的车厢,让新的车厢指向车厢3,这样就会在两节车厢中间加入新的车厢。
这么一说应该就明白了,如果不明白,那么就该放弃数据结构了。链表没有容器这个概念了。如果有,就看你的内存有多大了。
代码实现 :
单向链表实现的是List接口:
存储单元:存储的是一个个节点
节点是什么:节点是一个内部类,里面包含自身数据和一个指向。看过千手观音吧,从正面看就是一个人,里面实际有很多人,链表的存储结构就好像,是在一维里面开辟出多维。也可以这样说,你打开一个箱子,箱子里面有两部分,一部分装着数据一部分装着另一个箱子
打开箱子0里面有数据0和箱子1,打开箱子1里面有数据1和箱子2,打开箱子2 里面有数据2和箱子3 直至结束。
代码实现
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* 单向链表结构
*
* @author sc
* @since v1.0.0
*/
public class MyLinkedList {
//链表的首个节点
private Node firstNode;
//链表的长度
private int size = 0;
//给链表增加一个节点
public void add(Object data) {
Node newNode = new Node();
newNode.setData(data);
if (this.size == 0) {
this.firstNode = newNode;
} else {
// 获取最后一个节点
Node lastNode = this.firstNode;
for (int i = 0; i < this.size - 1; i++) {
lastNode = lastNode.getNextNode();
}
lastNode.setNextNode(newNode);
}
this.size++;
}
//使用下标获取链表中的某个节点的值
public Object get(int index) {
checkRange(index);
Node lastNode = this.firstNode;
if (index == 0) {
if (this.size == 0) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
} else {
return lastNode;
}
} else {
for (int i = 0; i < index; i++) { // 0 1
lastNode = lastNode.getNextNode();
}
}
return lastNode;
}
//使用下标移除链表中的某个节点
public void remove(int index) {
checkRange(index);
if (index == 0) {
if (this.size == 0) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
} else {
this.firstNode = this.firstNode.getNextNode();
}
} else {
Node lastNode = this.firstNode;
for (int i = 0; i < index; i++) { // 0 1
lastNode = lastNode.getNextNode();
}
}
size--;
}
//获取链表长度
public int getSize() {
return this.size;
}
// 边界判断
private void checkRange(int index) {
if (index > this.size) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
}
// 输出
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + size;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("firstNode", firstNode)
.append("size", size)
.toString();
}
}
class Node {
//下一个节点
private Node nextNode;
//节点中的数据
private Object data;
public Node getNextNode() {
return nextNode;
}
public void setNextNode(Node nextNode) {
this.nextNode = nextNode;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("nextNode", getNextNode())
.append("data", getData())
.toString();
}
}