理解
点击这里查看大图
每一个圆代表一个节点,里面存放了相应的数据,每个节点连接着另一个节点,从而连成一条线。如果要做个类比,有点像行走在沙漠中的骆驼队:
点击这里查看大图
骆驼——节点
货物——数据(好吧,图中的骆驼没有背货物)
绳子——用来连接下一个节点
插入数据
1. 插入到末尾
点击这里查看大图
很简单,只需将链表末尾的节点指向新的节点。
类比骆驼队:如果新骆驼要加入到队伍的末尾,只需用一根绳子,将新骆驼绑到最后一个骆驼上就可以了。
2.插到头部
点击这里查看大图
也很简单,只需将新节点与链表的头节点建立连接。
类比骆驼队:如果新骆驼要加入到队伍的开头,只需将队伍中的第一个骆驼绑到新骆驼上就可以了。
3. 一般情况
一般性操作稍微复杂一点:
1. 节点2与节点3断开连接
2. 节点2与新节点建立连接
3. 新节点与节点3建立连接
类比骆驼队:
1. 松开两个骆驼之间的绳子
2. 将新骆驼绑到前一个骆驼上
3. 将后一个骆驼绑到新骆驼上
移除数据
1. 移除开头
点击这里查看大图
很简单,只需将头节点与后面一个节点断开连接,这样,链表就是以后一个节点为头结点了。
类比骆驼队:要拿掉队伍开头的骆驼,只需该骆驼与后面队伍连接的绳子拿掉就可以了。
2. 移除末尾
点击这里查看大图
也很简单,只需将末尾的节点与前一个节点断开连接就可以了。这样,链表就是以之前链表末尾节点的前一个节点为末尾节点的链表了(反应到图中,就是以节点4位末尾节点的链表)
类比骆驼队,要拿掉队伍末尾的骆驼,只需将该骆驼与前面队伍连接的绳子拿掉就可以了。
3.一般情况
点击这里查看大图
一般情况的操作稍微复杂一些:
1. 节点2与节点3断开连接
2. 节点3与节点4断开连接
3. 节点2与节点4建立连接
类比骆驼队
1. 前一个骆驼与该骆驼之间的绳子拿掉
2. 该骆驼与后一个骆驼之间的绳子拿掉
3. 前一个骆驼与后一个骆驼之间用绳子拴起来
Java代码实现及演示
实现代码
public class MySingleList {
//头结点
private Node first;
//末尾节点
private Node last;
//大小
private int size = 0;
//插入
public void insert(int i, String s) {
if (i < -1) {
throw new IllegalArgumentException("i不能小于0");
}
if (i > size) {
throw new IllegalArgumentException("i不能大于链表的长度");
}
Node node = new Node(s, null);
//第一次插入数据
if (first == null) {
first = node;
last = node;
size++;
look();
return;
}
//插入到链表的末尾
if (i == size) {
last.next = node;
last = node;
size++;
look();
return;
}
//插入头
if (i == 0) {
node.next = first;
first = node;
size++;
look();
return;
}
//一般情况
//找出相应的节点
Node preNode = selectNode(i - 1);
Node nextNode = preNode.next;
preNode.next = node;
node.next = nextNode;
size++;
look();
}
//移除
public void remove(int index) {
if (index < -1) {
throw new IllegalArgumentException("index不能小于0");
}
if (index > size - 1) {
throw new IllegalArgumentException("index不能大于链表的长度-1");
}
//1.移除头部
if (index == 0) {
Node oldFirst = first;
first = first.next;
oldFirst.s = null;
oldFirst.next = null;
oldFirst = null;
size--;
look();
return;
}
//2.移除尾部
if (index == size - 1) {
Node oldLast = last;
Node newLast = selectNode(size - 2);
newLast.next = null;
last = newLast;
oldLast.s = null;
oldLast = null;
size--;
look();
return;
}
//3.一般情况下的处理
Node preNode = selectNode(index - 1);
Node node = preNode.next;
Node nextNode = node.next;
preNode.next = nextNode;
node.next = null;
node.s = null;
node = null;
size--;
look();
}
public void clear() {
//链表如果为空,不做处理
if (first == null)
return;
Node p = first;
Node q;
while (p != null) {
q = p.next;
p.s = null;
p.next = null;
p = q;
}
first = null;
last = null;
size = 0;
System.out.println("数据清空");
look();
}
//找出指定的节点
private Node selectNode(int i) {
if (i < -1) {
throw new IllegalArgumentException("i不能小于0");
}
if (i > size - 1) {
throw new IllegalArgumentException("i不能大于链表的长度-1");
}
//i为0时的处理
if (i == 0)
return first;
//i为size-1时的处理
if (i == size - 1)
return last;
//处理头结点和末尾节点可以直接获取,其余的节点需要遍历才能获取到
int index = 0;
Node node = first;
while (node != null && index < i) {
index++;
node = node.next;
}
return node;
}
//节点类
class Node {
public String s;
public Node next;
public Node(String s, Node next) {
this.s = s;
this.next = next;
}
}
//用来查看链表中的数据
private void look() {
Node node = first;
System.out.println("");
while (node != null) {
System.out.print(node.s + " ");
node = node.next;
}
}
public int getSize() {
return size;
}
}
插入操作演示
public class Main {
public static void main(String[] args) {
MySingleList list = new MySingleList();
list.insert(0,"1");
list.insert(1,"2");
list.insert(0,"3");
list.insert(0,"4");
list.insert(0,"5");
list.insert(3,"6");
list.insert(5,"7");
list.insert(6,"8");
list.insert(7,"9");
}
}
结果
1
1 2
3 1 2
4 3 1 2
5 4 3 1 2
5 4 3 6 1 2
5 4 3 6 1 7 2
5 4 3 6 1 7 8 2
5 4 3 6 1 7 8 9 2
移除及清空代码演示
public class Main {
public static void main(String[] args) {
MySingleList list = new MySingleList();
list.insert(0,"1");
list.insert(1,"2");
list.insert(2,"3");
list.insert(3,"4");
list.insert(4,"5");
list.insert(5,"6");
list.remove(5);
list.remove(0);
list.remove(1);
list.clear();
}
}
结果
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5
2 3 4 5
2 4 5 数据清空
结语
Java中LinkedList已经对这些操作进行了封装,我们可以直接使用
转载请标明出处:http://blog.youkuaiyun.com/qq_26411333/article/details/51813833