数据结构--LinkedList的java实现

时间:2023-02-04 10:16:39

上代码:

package com.itany.MyLinkedList;

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyLinkedList<T> implements Iterable<T>
{
private int theSize;
private int modCount=0;
private Node<T> beginMarker;
private Node<T> endMarker;

public MyLinkedList()
{
clear();
}
private static class Node<T>
{
private T data;
private Node<T> prev;
private Node<T> next;
public Node(T d,Node<T> p,Node<T> n)
{
this.data=d;
this.prev=p;
this.next=n;
}
}
//清除所有内容 实际上就是把集合的begin和end重新赋值一个新的,再把首尾连起来
public void clear()
{
theSize=0;
beginMarker=new Node<T>(null,null,null);
endMarker=new Node<T>(null,beginMarker,null);
beginMarker.next=endMarker;
modCount++;
}
public boolean isEmpty()
{
return theSize==0;
}
public int size()
{
return theSize;
}
public void add(T t)
{
add(size(),t);
}
public void add(int idx,T t)
{
addBefore(getNode(idx),t);
}
public T remove(int idx)
{
return remove(getNode(idx));
}
public T set(int idx,T newT)
{
Node<T> p=getNode(idx);
T old=p.data;
p.data=newT;
return old;
}
//所有的add get set remove操作都是对序号进行操作 这要求我们必须在集合内部自己实现通过序号查找到具体Node 在对Node进行操作的addBefore
//remove 和getNode这三个基本方法 注意:这三个*类中的基本方法时私有的 外部无法访问 只能在*类内部调用
private void addBefore(Node<T> node,T t)
{
Node<T> newT=new Node<T>(t,node.prev,node);
node.prev.next=newT;
node.prev=newT;
theSize++;
modCount++;
}
private T remove(Node<T> node)
{
node.prev.next=node.next;
node.next.prev=node.prev;
theSize--;
modCount++;
return node.data;
}
//因为node中没有序号 所以要找到对应Index的node必须 使用遍历 一个个通过默认序号(从0开始)来查找到
//为了查找是更快 所以需要对index的大小分类 以确定是从头开始找还是从末尾
//功能是获得对应序号的节点
private Node<T> getNode(int idx)
{
Node<T> p;
//idx==size()的情况是有一种add是直接加载链表后面顺序加入
if(idx<0 || idx>size())
throw new ArrayIndexOutOfBoundsException();
//如果插入的idx序号考前 则从beginMarker开始遍历
if(idx<size()/2)
{
p=beginMarker.next;
//此处idx是几循环就要走几次
for(int i=0;i<idx;i++)
p=p.next;
}
//如果插入的idx序号考后 则从endMarker开始遍历
else
{
//注意 如果是默认插入到最后 那么会调用add(t),add(size(),t) 也就是addBefore(node,t) 此处的node就是size()对应的node 即endMarker
p=endMarker;
//如果插在最后 那么不会进入for循环
for(int i=size();i>idx;i--)
p=p.prev;
}
return p;
}
public Iterator<T> iterator()
{
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator<T>
{
//为了检测在迭代期间集合被修改的情况是否一致
private int expectedModCount=modCount;
//要求必须在next之后才允许删除
private boolean okToRemove=false;
private Node<T> current=beginMarker.next;
//别被名字所迷惑了 实际上在此处就是 hasCurrent
public boolean hasNext()
{
return current!=endMarker;
}
public T next()
{
if(expectedModCount!=modCount)
throw new ConcurrentModificationException();
if(!hasNext())
throw new NoSuchElementException();
T t=current.data;
okToRemove=true;
current=current.next;
return t;
}
//注意 迭代器的remove是没有返回值的
public void remove()
{
if(!okToRemove)
throw new IllegalStateException();
if(expectedModCount!=modCount)
throw new ConcurrentModificationException();
MyLinkedList.this.remove(current.prev);
okToRemove=false;
expectedModCount++;
}
}
}
package com.itany.MyLinkedList;import java.util.Iterator;public class Test{        public static void main(String[] args)    {        MyLinkedList<Integer> my=new MyLinkedList<Integer>();        my.add(22);        my.add(13);        my.add(45);        my.add(1,15);        my.add(7,16);        Iterator<Integer> it=my.iterator();        while(it.hasNext())        {            System.out.println(it.next()+"  ");        }    }    }