小黑爱学习之简单模拟实现LinkedList(使用双向链表)
LinkedList是JAVA容器中常用的一个实现类,它的底层是由双向链表实现的。它的特点主要有查询效率低,增删效率高,线程不安全等,适由于频繁的增删的情况。
1,双向链表
双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向前一个节点和后一个节点。
所以,从双向链表中的任意一个节点开始,都可以很方便地找到所有节点。
2,模拟实现LinkedList
(1)定义一个节点类(MyNode)
/**
*定义一个节点类
*/
public class MyNode {
MyNode previous; //上一个节点
MyNode next; //下一个节点
Object element; //节点数据元素
public MyNode(MyNode previous, MyNode next, Object element) {
super();
this.previous = previous;
this.next = next;
this.element = element;
}
public MyNode(Object element) {
super();
this.element = element;
}
}
(2) 模拟LinkedList,主要有添加节点、删除节点、插入节点、拿到节点等方法。
public class MyLinkedList<E> {
private MyNode first;//前驱节点
private MyNode last;//后继节点
private int size;//链表总长度
//get去特定索引的节点数据方法的实现
public E get(int index) {
checkRange(index);
MyNode node=getNode(index);
return node!=null?(E)node.element:null;
}
//remove删除节点方法
public void remove(int index) {
checkRange(index);
MyNode node=getNode(index);//得到节点
if(node!=null) {
MyNode prior=node.previous;//前一个结点
MyNode rear=node.next;//后一个节点
if(prior!=null) {
prior.next=rear;
}
if(rear!=null) {
rear.previous=prior;
}
if(index==0) {//被删除的元素是第一个元素时
first=rear;
}
if(index==size-1) {//被删除的元素是第二个元素时
last=prior;
}
size--;
}
}
//insert在特定索引位置插入新节点的方法
public void insert(int index,E element) {
checkRange(index);
MyNode newNode=new MyNode(element);//建立一个新结点
MyNode node=getNode(index);//获得特定索引位置的节点
if(index==size-1) {//最后的索引位置插入
last=newNode;
node.next=newNode;
newNode.previous=node;
}else {
if(node!=null) {
MyNode prior=node.previous;//特定节点的前一个节点
if(prior==null) {//在第一个索引位置插入
first=newNode;
newNode.next=node;
node.previous=newNode;
}else {
prior.next=newNode;
newNode.previous=prior;
newNode.next=node;
node.previous=newNode;
}
}
}
size++;
}
//getNode拿到相应索引的节点数据方法
public MyNode getNode(int index) {
checkRange(index);
MyNode node=null;
if(index<size>>1) {//size>>1相当于size/2
node=first;
for(int i=0;i<index;i++) {
node=first.next;
}
}else {
node=last;
for(int i=size-1;i>index;i--) {
node=last.previous;
}
}
return node;
}
//add添加节点方法
public void add(E element) {
MyNode node= new MyNode(element);//创建一个节点
if(first==null) {
first=node;
last=node;
size++;
}else {
node.previous=last;
node.next=null;
last.next=node;
last=node; //修改尾节点
size++;
}
}
//索引的检查
private void checkRange(int index) {
if(index<0||index>size-1) {
throw new RuntimeException("索引超出范围");
}
}
//重写toString方法
@Override
public String toString() {
StringBuilder so=new StringBuilder();
MyNode temp=first;
so.append("[");
while(temp!=null) {
so.append(temp.element+",");
// System.out.println(temp.element);
temp=temp.next;//下一个元素
}
so.setCharAt(so.length()-1, ']');
return so.toString();
}
public static void main(String[] args) {
MyLinkedList <String>list=new MyLinkedList<String>();
list.add("a");//测试add方法
list.add("b");
list.add("c");
list.add("d");
list.add("e");
System.out.println(list);
System.out.println(list.get(1));//测试get方法
list.insert(4, "n");//测试insert方法
System.out.println(list);
list.remove(0);//测试删除方法
System.out.println(list);
}
}