package assignment; public class MyLinkedList<E> implements List<E>, Iterable<E> { private Node<E> head; private int size; public MyLinkedList() { size = 0; } public void add(E o) { if (head == null) addFirst(o); else addLast(o); } public void addFirst(E o) { Node<E> oldFirst = head; head = new Node<>(o, oldFirst); size++; } public void addLast(E o) { if (head == null) { addFirst(o); } else { Node<E> oldLast = movePtrTo(size - 1); oldLast.next = new Node<>(o, null); size++; } } public void add(int index, E o) { if (index > size || index < 0) { throw new IllegalArgumentException("index:" + index); } if (index == 0) { addFirst(o); return; } Node<E> temp = movePtrTo(index - 1); Node<E> oldNext = temp.next; Node<E> newNext = new Node<>(o, oldNext); temp.next = newNext; size++; } public E remove(int index) { rangeCheck(index); E data; if (index == 0) { data = head.data; head = head.next; } else { Node<E> pre = movePtrTo(index - 1); Node<E> target = pre.next; pre.next = target.next; data = target.data; } size--; return data; } public E get(int index) { rangeCheck(index); return movePtrTo(index).data; } public int size() { return size; } private Node<E> movePtrTo(int index) { Node<E> resultNode = head; for (int i = 0; i < index; i++) { resultNode = resultNode.next; } return resultNode; } private void rangeCheck(int index) { if (index >= size) { throw new NoSuchElementException("index:" + index + ",size:" + size); } } @Override public String toString() { if (size == 0) { return "[]"; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("["); Node<E> temp = head; while (temp != null) { stringBuilder.append(String.valueOf(temp.toString()) + ","); temp = temp.next; } stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length()); stringBuilder.append(']'); return stringBuilder.toString(); } private static class Node<T> { private T data; private Node<T> next; public Node(T data, Node<T> next) { this.data = data; this.next = next; } @Override public String toString() { return data.toString(); } } @Override public Iterator<E> iterator() { return new ListIterator(); } private class ListIterator implements Iterator<E> { Node<E> currentNode; public ListIterator() { currentNode = head; } @Override public boolean hasNext() { return currentNode != null; } @Override public E next() { Node<E> temp = currentNode; currentNode = currentNode.next; return temp.data; } } /** * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse() { if (head == null || head.next == null) { return; } Node<E> node1 = head; Node<E> node2 = head.next; head.next = null; Node<E> node3 = node2.next; while (node3 != null) { node2.next = node1; node1 = node2; node2 = node3; node3 = node3.next; } head = node2; head.next = node1; } /** * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 * ,删除以后的值为7,8,10 * */ public void removeFirstHalf() { remove(0, size / 2); } /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * * @param i * @param length */ public void remove(int i, int length) { rangeCheck(i + length - 1); size -= length; if (i == 0) { head = movePtrTo(i + length - 1).next; return; } Node<E> node = movePtrTo(i - 1); Node<E> newNext = movePtrTo(i + length - 1).next; node.next = newNext; } /** * 假定当前链表和list均包含已升序排列的整数 从当前链表中取出那些list所指定的元素 例如当前链表 = * 11->101->201->301->401->501->601->701 listB = 1->3->4->6 * 返回的结果应该是[101,301,401,601] * * @param list */ public int[] getElements(MyLinkedList<Integer> list) { int[] result = new int[list.size()]; Iterator<Integer> iterator = list.iterator(); int index = 0; while (iterator.hasNext()) { System.out.println(index); result[index++] = (Integer) (movePtrTo(iterator.next()).data); } return result; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 * * @param list */ public void subtract(MyLinkedList list) { if (list == null || list.size() == 0) { return; } Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { subtract(iterator.next()); } } private void subtract(int value) { int index = 0; Node<E> temp = head; while (temp != null) { if ((Integer) temp.data != value) { temp = temp.next; index++; } else { remove(index); break; } } } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues() { int index = 0; Node<E> temp = head; while (temp.next != null) { if (temp.data.equals(temp.next.data)) { remove(index + 1); } else { index++; temp = temp.next; } } } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * * @param min * @param max */ public void removeRange(int min, int max) { if (min >= max) throw new IllegalArgumentException("min<=max"); if (head == null || (Integer) head.data >= max) return; Node<Integer> minPtr = (Node<Integer>) head; Node<Integer> maxPtr = (Node<Integer>) head; if ((Integer) head.data > min) { while (maxPtr.data < max) { maxPtr = maxPtr.next; head = (Node<E>) maxPtr; size--; if (size == 0) { head = null; return; } } } else { while (minPtr.next != null && minPtr.next.data <= min) { minPtr = maxPtr = minPtr.next; } maxPtr = maxPtr.next; while (maxPtr != null && maxPtr.data < max) { maxPtr = maxPtr.next; size--; } } minPtr.next = maxPtr; } /** * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * * @param list */ public MyLinkedList<Integer> intersection(MyLinkedList<Integer> list) { MyLinkedList<Integer> resultList = new MyLinkedList<>(); Node<Integer> ptr1 = (Node<Integer>) head; Node<Integer> ptr2 = list.head; while (ptr1 != null && ptr2 != null) { if (ptr1.data.equals(ptr2.data)) { resultList.add(ptr1.data); ptr1 = ptr1.next; ptr2 = ptr2.next; continue; } if (ptr1.data < ptr2.data) { ptr1 = ptr1.next; } else { ptr2 = ptr2.next; } } return resultList; } public static void main(String[] args) { MyLinkedList<Integer> linkedList = new MyLinkedList<>(); // 11->101->201->301->401->501->601->701 listB = 1->3->4->6 linkedList.add(10); linkedList.add(11); linkedList.add(201); linkedList.add(301); linkedList.add(401); linkedList.add(501); MyLinkedList<Integer> linkedList2 = new MyLinkedList<>(); linkedList2.add(501); System.out.println(linkedList + "" + linkedList.size()); System.out.println(linkedList2 + "" + linkedList2.size()); System.out.println(linkedList.intersection(linkedList2)); } }