实现LinkedBox类
LinkedList在实现时与ArrayList的区别是,LinkedList底层是使用双向链表,而ArrayList则是使用数组。因此LinkedList的好处是:
便于增加和删除,且效率更高,开销更小;无需关注长度问题;
当然也有不好:
无法实现轮询遍历;如果中间有一个节点出了问题,那么很多数据都将无法再访问到。
通过写LinkedBox类实现简化版LinkedList,加深理解
代码实现
1、节点类
由于LinkedBox类使用的是链表数据结构,存储数据的单位是节点,因此我们需要创建节点类。
package mybox;
public class Node {
//定义节点
public Node prev;//存储上一个节点的地址
public int item;//当前数据
public Node next;//下一个节点的地址
public Node(Node prev,int item,Node next){
this.prev = prev;
this.item = item;
this.next = next;
}
}
为了查找元素方便,所以选用的是双向链表结构,这样不管从链头还是链尾查找都可以。图示:
2、LinkedBox
package mybox;
//链表 链式方法-->数据结构 单项链表 双向链表
//模拟数组的作用
public class LinkedBox implements Box {
//
private Node first;//头结点
private Node last;//尾节点
private int size;//记录有效数据数量
//将元素添加在新的node里
private void linkLast(int element) {
//获取链表的尾节点
Node l = last;
//创建一个新的node对象,将新数据包装起来
Node newNode = new Node(l, element, null);
//将新节点对象设置为为尾节点
last = newNode;
//严谨性判断
if (l == null) {//如果原来尾节点没有对象,证明这个链表是没有使用过的
first = newNode;
} else {
//已经有其他节点存在了
l.next = newNode;
}
//有效元素个数增加一个
size++;
}
//设计一个方法,负责检测index
private void rangeCheck(int index) {
if(index<0 || index>=size)
{
//自定义一个异常 来说明问题
throw new BoxIndexOutOfBoundsException("Index"+index+",Size"+size);
}
}
//设计一个方法 负责找寻index对应的对象
private Node findNode(int index){
Node targetNode;//存储找到的当前那个对象
//判断index范围是在链表前半部分还是后半部分
if(index < (size >> 1)){
//从前往后找比较快
targetNode=first;
for(int i=0;i<=index;i++){
targetNode = targetNode.next;
}
}else{
//从后往前找比较快
targetNode=last;
for(int i=size-1;i>=index;i--){
targetNode = targetNode.prev;
}
}
return targetNode;
}
//设计一个方法 ,将指定节点删掉 并返回被删除节点的值
private int unLink(Node targetNode){
int oldValue = targetNode.item;//取出要删除的这个元素的值
Node prevNode = targetNode.prev;//当前node的前一个
Node nextNode = targetNode.next;//当前node的后一个
if(prevNode==null){
first = nextNode;
}else{
prevNode.next = nextNode;
targetNode.prev = null;
}
if(nextNode==null){//当前node是最后一个
last = prevNode;
}else{
nextNode.prev = prevNode;
targetNode.next = null;
}
size--;
return oldValue;
}
//上面都是封装起来
//-----------------------------------------------------------
//下面是供用户使用的
public boolean add(int element) {
//将element存入一个对象里添加至链表的尾端
this.linkLast(element);
//告知添加成功
return true;
}
public int get(int index) {
//检测index是否合法
this.rangeCheck(index);
//找到对应的node
Node targetNode = this.findNode(index);
//返回找到的node对象内的数据
return targetNode.item;
}
public int remove(int index) {
this.rangeCheck(index);
Node targetNode = this.findNode(index);
int oldValue = this.unLink(targetNode);
return oldValue;
}
public int size() {
return size;
}
public void show() {
Node node=first;
while(node.next!=null){
System.out.print(node.item+" ");
node=node.next;
}
System.out.print(node.item+" ");
}
}