package ListServiceImpl; import java.util.Iterator; import ListService.KILinkedList; public class KLinkedList<T> implements Iterable<T>, KILinkedList<T> { // 记录链表的长度 private int mSize = 0; // private int mActionCount = 0; // 开始和结束节点 private Node<T> mBeginNode, mLastNode; public KLinkedList() { // TODO Auto-generated constructor stub init(); } /** * 初始化一个只有开始节点和结束节点的空链表 */ private void init() { // 将首位节点链接起来 mBeginNode = new Node<T>(null, null, null); mLastNode = new Node<T>(null, mBeginNode, null); mBeginNode.nextNode = mLastNode; mSize = 0; // mActionCount++; } public int size() { return mSize; } public boolean isEmpty() { return mSize == 0 ? true : false; } /** * 在链表的pos位置之前放置t_node这个节点 * * @param t_node * 需要放置的节点 * @param pos * 放置节点在pos之前 */ private void add(Node<T> newNode, int pos) { // 抛出不合法的位置 if (pos < 0 || pos > mSize) { throw new IndexOutOfBoundsException(); } // 链接新节点 newNode.nextNode = getNode(pos); getNode(pos - 1).nextNode = newNode; getNode(pos).preNode = newNode; // mActionCount++; mSize++; } /** * t 供外部调用,直接在链表的末尾添加,即在mLastNode节点之前 * * @param */ public void add(T t) { add(new Node<T>(t, null, null), mSize); } /** * 往链表pos位置之前添加数据t * * @param t * 添加的数据 * @param pos * 添加在pos位置之前 */ public void add(T t, int pos) { add(new Node<T>(t, null, null), pos); } /** * * @param pos * 链表中的某个位置 * @return 翻去pos位置的节点 (此处的pos的范围是[-1,mSize],此方法是私有方法,外部访问不了,只共此类中呢个访问) */ private Node<T> getNode(int pos) { Node<T> node; int currentPos; if (pos == -1) { // -1的位置是开始节点 return mBeginNode; } else if (pos == mSize) { // mSize的位置是结束的节点 return mLastNode; } // 因为这是双向节点,所以判断一下能提高搜索效率 if (pos < mSize / 2) { currentPos = 0; node = mBeginNode.nextNode; while (currentPos < pos) { node = node.nextNode; currentPos++; } } else { node = mLastNode.preNode; currentPos = mSize - 1; while (currentPos > pos) { node = node.preNode; currentPos--; } } return node; } public T get(int pos) { return getNode(pos).t; } public void set(T t, int pos) { if (pos < 0 || pos >= mSize) { throw new IndexOutOfBoundsException(); } getNode(pos).t = t; } /** * 删除特定位置的节点 * * @param t_node * 需要删除节点的位置 * @return */ private T remove(Node<T> t_node) { t_node.preNode.nextNode = t_node.nextNode; t_node.nextNode.preNode = t_node.preNode; // 最好在此处给其设置为空,不要其链接到其他节点,因为已经被销毁,不再持有其他的节点的引用 t_node.nextNode = null; t_node.preNode = null; mSize--; // mActionCount++; return t_node.t; } public T remove(int pos) { if (pos < 0 || pos >= mSize) { throw new IndexOutOfBoundsException(); } Node<T> tempNode = getNode(pos); remove(tempNode); return tempNode.t; } public Iterator<T> iterator() { return new MyLinkedListIterator<T>(); } private class MyLinkedListIterator<T> implements Iterator<T> { private int currentPos = 0; public boolean hasNext() { // TODO Auto-generated method stub if (currentPos < mSize) { return true; } return false; } public T next() { // TODO Auto-generated method stub return (T) getNode(currentPos++).t; } public void remove() { // TODO Auto-generated method stub KLinkedList.this.remove(getNode(--currentPos)); ; } } // 静态内部类,定义的节点,双向链表,需要一个指向前面一项的引用域和一个指向后面一项的引用域,方便查找 private static class Node<T> { public T t; public Node<T> preNode; public Node<T> nextNode; public Node(T t, Node<T> preNode, Node<T> nextNode) { this.preNode = preNode; this.nextNode = nextNode; this.t = t; } } }