package com.coding.basic.list; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * Korben's LinkedList * * Created by Korben on 18/02/2017. */ public class KLinkedList<T> implements KList<T> { private int size; private Node<T> head; private Node<T> last; public KLinkedList() { this.head = new Node<>(null); } @Override public int size() { return this.size; } @Override public boolean isEmpty() { return this.size == 0; } @Override public boolean contains(Object o) { Node node = this.head; while (node.next != null) { node = node.next; if (Objects.equals(node.data, o)) { return true; } } return false; } @Override public Object[] toArray() { throw new IllegalStateException("方法未实现"); } @Override public boolean add(T o) { if (this.last == null) { this.last = new Node<>(o); this.head.next = this.last; } else { Node<T> oldLast = this.last; this.last = new Node<>(o); oldLast.next = this.last; } this.size++; return true; } @Override public boolean remove(T o) { Node node = this.head; Node preNode; while (node.next != null) { preNode = node; node = node.next; if (Objects.equals(node.data, o)) { removeNode(preNode, node); return true; } } return false; } @Override public void clear() { this.head.next = null; this.last = null; this.size = 0; } @Override public T get(int index) { return getNode(index).data; } @Override public T set(int index, T element) { Node<T> node = getNode(index); node.data = element; return element; } @Override public void add(int index, T element) { ensureIndex(index); Node<T> node = this.head; Node<T> preNode = node; for (int i = 0; i <= index; i++) { preNode = node; node = node.next; } Node<T> newNode = new Node<>(element); newNode.next = node; preNode.next = newNode; this.size++; } @Override public T remove(int index) { ensureIndex(index); Node<T> node = this.head; Node<T> preNode = this.head; for (int i = 0; i <= index; i++) { preNode = node; node = node.next; } preNode.next = node.next; if (node == last) { last = preNode; } this.size--; return node.data; } @Override public int indexOf(T o) { Node node = this.head; int index = 0; while (node.next != null) { node = node.next; if (Objects.equals(node.data, o)) { return index; } index++; } return -1; } @Override public KIterator<T> iterator() { return new Iterator(); } private Node<T> getNode(int index) { ensureIndex(index); Node<T> node = this.head; for (int i = 0; i <= index; i++) { node = node.next; } return node; } /** * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse() { // 链表为空, 不用逆置, 返回 if (this.head.next == null) { return; } // 只有一个元素, 不用逆置, 返回 if (this.head.next.next == null) { return; } this.last = this.head.next; Node<T> preNode = this.head.next; Node<T> node = preNode.next; Node<T> nextNode = node.next; while (nextNode != null) { node.next = preNode; preNode = node; node = nextNode; nextNode = nextNode.next; } node.next = preNode; this.head.next = node; } /** * 删除一个单链表的前半部分 * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf() { if (isEmpty()) { return; } int halfIndex = (this.size) / 2; if (halfIndex >= 0) { this.head.next = getNode(halfIndex); } this.size -= halfIndex; } /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 */ public void remove(int i, int length) { ensureIndex(i); ensureIndex(i + length - 1); int newSize = this.size - length; // 得到被删除起始元素的前一个节点 Node<T> preNode; if (i == 0) { preNode = this.head; } else { preNode = getNode(i - 1); } // 得到最后一个被删除的元素 Node<T> node = preNode.next; while (--length > 0) { node = node.next; } // 删除元素 preNode.next = node.next; // 如果被删除的元素包含最后的节点, 改变最后节点 if (i + length == this.size - 1) { this.last = preNode; } this.size = newSize; } /** * 假定当前链表和list均包含已升序排列的整数 * 从当前链表中取出那些list所指定的元素 * 例如当前链表 = 11->101->201->301->401->501->601->701 * listB = 1->3->4->6 * 返回的结果应该是[101,301,401,601] */ public int[] getElements(KLinkedList list) { if (list == null || list.size == 0) { return new int[0]; } List<Integer> resultList = new ArrayList<>(); Node node = this.head; KIterator listIterator = list.iterator(); int elementIndex = (int) listIterator.next(); for (int i = 0; i < this.size; i++) { node = node.next; if (elementIndex == i) { resultList.add((Integer) node.data); if (listIterator.hasNext()) { elementIndex = (int) listIterator.next(); } else { break; } } } // list 2 array int[] result = new int[resultList.size()]; for (int i = 0; i < resultList.size(); i++) { result[i] = resultList.get(i); } return result; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 从当前链表中中删除在list中出现的元素 */ public void subtract(KLinkedList<Integer> list) { if (list == null || list.size() == 0) { return; } KIterator<Integer> listIterator = list.iterator(); Node node = this.head; Node pre; while (listIterator.hasNext()) { int listData = listIterator.next(); while (node.next != null) { pre = node; node = node.next; if (listData == (int) node.data) { removeNode(pre, node); } else if (listData < (int) node.data) { break; } } } } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues() { if (this.size() <= 1) { return; } Node node = this.head; Node pre; while (node.next.next != null) { pre = node; node = node.next; if (node.data == node.next.data) { removeNode(pre, node); } } } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) */ public void removeRange(int min, int max) { Node preMinNode = null; Node maxNode = null; Node node = this.head; // get min and max int minIndex = -1; int maxIndex = -1; while (node.next != null) { maxIndex++; if (preMinNode == null) { minIndex++; if ((int) node.next.data == min) { preMinNode = node; } } else if ((int) node.next.data == max) { maxNode = node.next; } else if (maxNode != null && (int) node.next.data > (int) maxNode.data) { break; } node = node.next; } // do remove if (preMinNode != null) { if (maxNode != null) { preMinNode.next = maxNode.next; this.size -= maxIndex - minIndex + 1; if (preMinNode.next == null) { this.last = preMinNode; } } else { preMinNode.next = null; this.size = minIndex; this.last = preMinNode; } } } /** * 123456789876543 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 */ public KLinkedList intersection(KLinkedList list) { if (list == null || list.size() == 0) { return copyList(this); } if (this.isEmpty()) { return copyList(list); } KLinkedList resultList = new KLinkedList(); KIterator listIterator = list.iterator(); KIterator iterator = this.iterator(); Integer listValue = (Integer) listIterator.next(); Integer value = (Integer) iterator.next(); for (int i = 0; i < list.size() + this.size() - 1; i++) { if (listValue == null) { if (value != null) { resultList.add(value); continue; } else { break; } } if (value == null) { if (listValue != null) { resultList.add(listValue); listValue = (Integer) listIterator.next(); continue; } else { break; } } if (listValue <= value) { resultList.add(listValue); listValue = (Integer) listIterator.next(); value = (Integer) iterator.next(); } else { resultList.add(value); value = (Integer) iterator.next(); } } return resultList; } private KLinkedList copyList(KLinkedList linkedList) { if (linkedList == null) { return null; } KLinkedList result = new KLinkedList(); KIterator iterator = linkedList.iterator(); while (iterator.hasNext()) { result.add(iterator.next()); } return result; } private void ensureIndex(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(); } } private void removeNode(Node pre, Node node) { pre.next = node.next; this.size--; if (this.last == node) { this.last = pre; } } private static class Node<T> { T data; Node<T> next; Node(T data) { this.data = data; } } private class Iterator implements KIterator<T> { private Node<T> node; Iterator() { this.node = head; } @Override public boolean hasNext() { return node.next != null; } @Override public T next() { if (hasNext()) { node = node.next; return node.data; } return null; } } }