其实刚刚接触链表迭代器的时候并不知道这个有什么用,直到今天把链表迭代器的代码敲了两三遍,将里面的内容理解透彻了以后,才发现原来链表迭代器真的有很大用处,效率高是迭代器的一大优势。当我们需要在特定结点前面插入或者删除甚至修改该结点的值即data域的时候就会显得相当有用,若没有迭代器,只是一个普通的链表,当我们需要获取特定结点的,比如说第一个第二个或者第三个,我们又要从头开始遍历链表,并且还要引入一些变量,这样做效率低下。
举个实际应用的例子:
用一个链表存储学生成绩信息,我们要将所有不及格学号的学生挑出来,这时候我们就可以利用迭代器,效率会高得多。
以下只是一些基础代码,我们还可以在增添修改当前current结点data的方法以及获取当前结点的位置数,这些方法都比较容易实现,迭代器迭代器,说到底就是使用另外一个结点去指向用户所想找的结点。实质就是结点指结点。
/**
* 自定义结点类
* @author Administrator
*
*/
public class Link {
public int data;
public Link next;
public Link(int data) {
super();
this.data = data;
}
public void displayLink() {
System.out.print(data +" ");
}
}
/**
* 自定义链表类
* 初始化链表,其它操作如增删查改在迭代器中完成
* @author Administrator
*
*/
public class LinkList {
public Link first;
public LinkList() {
first = null;
}
public Link getFirst() {
return first;
}
public void setFirst(Link f) {
first = f;
}
public boolean isEmpty() {
return (first==null);
}
public ListIterator getIterator() {
return new ListIterator(this);
}
public void displayList() {
Link current = first;
while(current!=null) {
current.displayLink();
current = current.next;
}
System.out.println();
}
}
/**
* 自定义迭代器
* @author Administrator
*
*/
public class ListIterator {
public Link current;
private Link previous;
private LinkList ourList;
public ListIterator(LinkList list) {
ourList = list;
reset();
}
public void reset() {
current = ourList.getFirst(); //current指向链表的第一个结点
previous = null;
}
public Link getCurrent() {
return (current); //获取迭代器指向链表的当前结点
}
public boolean atEnd() {
return (current.next==null); //迭代器当前是否为最后一个结点
}
public void nextLink() {
previous = current; //将previous指向上一个current指向的结点
current = current.next; //将下一个结点赋给current
}
public void insertAfter(int num) { //在current后面插入一个结点
Link newLink = new Link(num);
if(ourList.isEmpty()) { //如果为空表
ourList.setFirst(newLink); //需设置空表的first结点
current = newLink; //将迭代器的当前结点指向新结点
}else {
newLink.next = current.next; //包含中间插入和尾部插入
current.next = newLink;
}
}
public void insertBefore(int num) {
Link newLink = new Link(num);
if(previous==null) { //若迭代器指向的是first
ourList.setFirst(newLink);
newLink.next = current;
reset(); //迭代器重置,仍然指向first结点
}else {
newLink.next = previous.next;
previous.next = newLink;
current = newLink; //迭代器指向新结点
}
}
public int deleteCurrent() {
int number = current.data;
if(previous==null) {
ourList.setFirst(current.next);
reset();
}else {
previous.next = current.next;
if(atEnd()) { //如果是最后一个结点则重置,指向first结点
reset();
}else {
current = current.next;
}
}
return number;
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 测试迭代器
* @author Administrator
*
*/
public class TestIterator {
public static void main(String[] args) throws IOException {
LinkList1 theList = new LinkList1();
ListIterator iter1 = theList.getIterator();
int number;
iter1.insertAfter(20);
iter1.insertAfter(40);
iter1.insertAfter(80);
iter1.insertBefore(60);
while(true) {
System.out.print("Enter first letter of show,reset, ");
System.out.println("next,get,before,after,delete: ");
System.out.flush();
int choice = getChar();
switch(choice) {
case 's': //show
if(!theList.isEmpty())
theList.displayList();
else
System.out.println("List is empty");
break;
case 'r': //reset
iter1.reset();
break;
case 'n': //next
if(!theList.isEmpty() && !iter1.atEnd())
iter1.nextLink();
else
System.out.println("Can't go to next link");
break;
case 'g': //getCurrent
if(!theList.isEmpty()) {
number = iter1.getCurrent().data;
System.out.println("Returned " + number);
}else
System.out.println("List is empty");
break;
case 'b': //insertBefore
System.out.println("Enter number to insert: ");
System.out.flush();
number = getInt();
iter1.insertBefore(number);
break;
case 'a': //insertAfter
System.out.println("Enter number to insert: ");
System.out.flush();
number = getInt();
iter1.insertAfter(number);
break;
case 'd': //deleteCurrent
if(!theList.isEmpty()) {
number = iter1.deleteCurrent();
System.out.println("Deleted " + number);
}else
System.out.println("Can't delete");
break;
default:
System.out.println("Invalid entry");
break;
}
}
}
public static String getString() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in); //InputStreamReader将字节流转化为字符流动
BufferedReader br = new BufferedReader(isr); //一次读取大量数据额大大提高效率
String s = br.readLine(); //读取一文本行
return s;
}
public static char getChar() throws IOException{
String s = getString();
return s.charAt(0);
}
public static int getInt() throws IOException{
String s = getString();
return Integer.parseInt(s); //解析一个字符串,并返回一个整数,若不能被转换为整型字符,会抛出异常
}
}