用迭代器优化链表
在单链表那篇文章中,我们实现了find()方法,根据指定的值找到结点。这个方法是从表头开始考察每个链结点,直到链接点的值和给定的值匹配
public Link find(int key){ Link current=first;//指向第一个结点 while (current.data1!=key){ if(current.next==null){ return null;//到达链表尾部返回null }else{ current=current.next;//没找到移到下一个结点 } } return current; }
其他的操作例如删除指定值得结点或者向前和向后插入新节点,都包含有链表上的搜索工作,以找到指定结点。但是这些方法都没有提供用户任何遍历上的控制手段。
在数组中,可以用下标跟踪所在位置。然后在链表中,没有固定的下标。使用find()方法虽然可以找到合适的链结点,但是这个方法要进行多次比较,效率就会很低。如果能从链结点到链接点步进,检查每个链接点是否符合某个标准,在执行操作,效率就会高很多。
这时我们就可以用到迭代器。那什么是迭代器呢?
迭代器就是一个引用,它被封装在一个类对象里面,并指向相关联的链表中的链结点。它里面封装了能对链接点进行某些操作的方法。
定义迭代器类
class ListIterator{ private Link current;//指向当前结点 private Link previous;//指向前一个 private LinkList ourList;//指向链表 //构造函数初始化 public ListIterator(LinkList list){ ourList=list; reset(); } //初始化变量 public void reset(){ current=ourList.getFirst(); previous=null; } //判断是否是最后一个 public boolean atEnd(){ return current.next==null; } public void nextLink(){ previous=current; current=current.next; } public Link getCurrent(){ return current; } }
增加和删除的方法
//在给定值结点后面插入 public void insertAfter(long dd){ Link newLink=new Link(dd);//新增的结点 //判断链表是否为空,为空则在表头插入 if(ourList.isEmpty()){ ourList.setFirst(newLink); current=newLink; }else{ newLink.next=current.next; current.next=newLink; nextLink(); } } //在给定值结点前面插入 public void insertBefore(long dd){ Link newLink=new Link(dd); //在表头前插入 if(previous==null){ newLink.next=ourList.getFirst(); ourList.setFirst(newLink); reset(); }else{ newLink.next=current; previous.next=newLink; current=newLink; } } //删除当前结点 public void deleteCurrent(){ long value=current.aData; //如果是表头 if(previous==null){ ourList.setFirst(current.next); reset(); }else{ previous.next=current.next; if(atEnd()){ reset();//迭代器达到结尾,返回开头 }else{ current=current.next; } } }
链接点类
//结点 public class Link { public long aData; public Link next; //构造函数初始化 public Link(long dd){ this.aData=dd; } public void displayLink(){ System.out.println(aData+","); } }
链表类
class LinkList{ private Link first; public LinkList(){ first=null; } public Link getFirst() { return first; } //设置表头 public void setFirst(Link first) { this.first = first; } public boolean isEmpty(){ return first==null; } public void displayList(){ Link current=first; while(current!=null){ current.displayLink(); current=current.next; } } //初始化迭代器 public ListIterator getIterator(){ return new ListIterator(this); } }
测试代码
public class Test { public static void main(String[] args) { LinkList list=new LinkList(); ListIterator it=list.getIterator(); it.insertAfter(1); it.insertAfter(2); it.insertAfter(3); it.insertAfter(4); it.insertBefore(5); list.displayList(); System.out.println("-----------------"); it.reset();//迭代器重置 //删除能整除3的数据 Link aLink =it.getCurrent(); if(aLink.aData%3==0){ it.deleteCurrent(); } while(!it.atEnd()){ it.nextLink(); aLink=it.getCurrent(); if(aLink.aData%3==0){ it.deleteCurrent(); } } list.displayList(); } }
结果
1, 2, 3, 5, 4, ----------------- 1, 2, 5, 4,