1.链表属于动态数据结构——需要多少空间开多少空间
- 链表是以节点的方式来存储,是链式存储
- 每个节点包含 data 域, next 域:指向下一个节点.,链表的各个节点不一定连续存储
- 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定
2.思路如下:
- 不能直接使用Node节点,客户端只关心数据的存储而不关心节点间的关系,因此将Node结点作为内部类隐藏起来
- LinkedList:相当于火车,具体连接每个节点,客户端使用此类
- Node:相当于火车车厢,存放数据
//简单实现三个位置的插入
package LinkedList;
/**
* LinkedList:相当于火车,具体连接每个节点,客户端使用此类
* Node:相当于火车车厢,存放数据
*/
public class LinkedList {
//火车头
private Node head;
//长度
private int size;
public LinkedList(){
head = null;
size = 0;
}
//客户端不能直接使用Node节点,客户端只关心数据的存储而不关心节点间的关系,因此将Node结点作为内部类隐藏起来
private class Node{
Object data;
Node next;
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Node(Object data) {
this.data = data;
}
}
/**
* 头插
* @param data 插入的数据
*/
public void addFirst(Object data){
//创建新节点
Node newNode = new Node(data);
//将当前节点的下一个节点指向链表的头结点
newNode.next = head;
//l链表的头结点变成当前节点
head = newNode;
size ++;
}
//插入第index节点的后面
public void add(int index, Object data){
//判断index是否合法
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("Index Illegal");
}
//头插
if(index == 0){
addFirst(data);
}
//找到index的前驱节点
Node prev = head;
for (int i = 1; i < index; i++) {
prev = prev.next;
}
Node newNode = new Node(data);
newNode.next = prev.next;
prev.next = newNode;
size ++;
}
//尾插
public void addLast(Object data){
add(size, data);
}
}
3.优化:设置一个虚拟头结点,保证任意位置存放数据都有前驱节点,将各种情况的解决归一化