package me.lzb.basic.list; /** * 简易LinkedList * Created by LZB on 2017/3/11. */ public class LinkedList implements List { private int size = 0; private Node first; private Node last; private static class Node { Object data; Node next; // int intData; public Node(Object data, Node next) { this.data = data; this.next = next; } // public Node(Object data, Node next, int i) { // this.data = data; // this.next = next; // this.intData = i; // } } // public void add(int i) { // if (first == null) { // first = new Node(null, null, i); // last = first; // } else { // Node n = new Node(null, null, i); // last.next = n; // last = n; // } // size = size + 1; // } public void add(Object o) { if (first == null) { first = new Node(o, null); last = first; } else { Node n = new Node(o, null); last.next = n; last = n; } size = size + 1; } // // public void addInt(int i) { // if (first == null) { // first = new Node(null, null, i); // last = first; // } else { // Node n = new Node(null, null, i); // last.next = n; // last = n; // } // size = size + 1; // } public void add(int index, Object o) throws IndexOutOfBoundsException { if (index < 0 || index > size) { throw new IndexOutOfBoundsException("index boom"); } if (index == size) { add(o); return; } if (index == 0) { Node n = new Node(0, first); first = n; size = size + 1; return; } Node before = first; for (int i = 0; i < index - 1; i++) { before = before.next; } Node after = before.next; Node n = new Node(o, after); before.next = n; size = size + 1; } private Node getNode(int index){ if (size == 0 || index < 0 || index >= size) { throw new IndexOutOfBoundsException("index boom"); } Node result = first; for (int i = 0; i < index; i++) { result = result.next; } return result; } public Object get(int index) { return getNode(index).data; } public Object remove(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("index boom"); } if (size == 1) { Node result = last; last = null; first = null; size = size - 1; return result.data; } if (index == size - 1) { Node result = last; last = null; size = size - 1; return result.data; } if (index == 0) { Node result = first; Node second = first.next; first = second; size = size - 1; return result.data; } Node before = first; for (int i = 0; i < index - 1; i++) { before = before.next; } Node result = before.next; Node after = before.next.next; before.next = after; size = size - 1; return result.data; } public int size() { return size; } public void addFirst(Object o) { add(0, o); } public void addLast(Object o) { add(o); } public Object removeFirst() { return remove(0); } public Object removeLast() { return remove(size); } public Iterator iterator() { return new LinkedListIterator(this); } private class LinkedListIterator implements Iterator { private LinkedList linkedList; int pos = 0; private LinkedListIterator(LinkedList linkedList) { this.linkedList = linkedList; } @Override public boolean hasNext() { if (pos >= linkedList.size) { return false; } return true; } @Override public Object next() { Object result = linkedList.get(pos); pos = pos + 1; return result; } } //后面的方法先不用写的说 /** * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse() { //还可以用堆栈 先进后出 if(size() <= 1){ return; } Object[] array = new Object[size]; Node tmp = first; for (int i = 0; i < size; i++) { array[i] = tmp.data; tmp = tmp.next; } this.first = null; this.last = null; for (int i = array.length - 1; i >= 0 ; i--) { add(array[i]); } } /** * 删除一个单链表的前半部分 * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf() { if (size <= 1){ return; } int b = size/ 2; Node n = getNode(b); this.first = n; size = (size % 2) + b; } /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * * @param i * @param length */ public void remove(int i, int length) { if (size == 0 || i < 0 || i >= size){ return; } length = size - i >= length ? length : size - i; if(i + length == size){ this.first = null; this.last = null; size = 0; return; } if(i == 0){ Node n = getNode(length); first = n; size = size - length; return; } Node a = getNode(i - 1); Node b = getNode(i + length); a.next = b; size = size - length; } /** * 假定当前链表和list均包含已升序排列的整数 * 从当前链表中取出那些list所指定的元素 * 例如当前链表 = 11->101->201->301->401->501->601->701 * listB = 1->3->4->6 * 返回的结果应该是[101,301,401,601] * * @param list */ public int[] getElements(LinkedList list) { if(size <= 0 || list.size() <= 0){ return new int[0]; } int[] result = new int[list.size()]; Node tmp = list.first; int index = 0; Node tmp2 = first; for (int i = 0; i < list.size(); i++) { int newIndex = (int)tmp.data; int maxJ = newIndex - index; for (int j = 0; j <= maxJ; j++) { if(j == maxJ){ result[i] = (int)tmp2.data; break; } tmp2 = tmp2.next; } index = newIndex; tmp = tmp.next; } size = size - list.size(); return result; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 从当前链表中中删除在list中出现的元素 * * @param list */ public void subtract(LinkedList list) { for (int i = 0; i < list.size(); i++) { this.remove(list.get(i)); } } public void remove(Object obj){ if(size <= 0){ return; } if(first.data.equals(obj)){ first=first.next; size = size - 1; return; } Node tmp = first; Node tmp2 = first.next; for (int i = 1; i < size; i++) { if(tmp2.data.equals(obj)){ tmp.next = tmp2.next; size = size - 1; return; } tmp = tmp.next; tmp2 = tmp2.next; } } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues() { if(size <= 1){ return; } Node tmp = first; for (int i = 1; i < size; i++) { if(tmp.next == null){ break; } if (tmp.data.equals(tmp.next.data)){ tmp.next = tmp.next.next; } tmp = tmp.next; } } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * * @param min * @param max */ public void removeRange(int min, int max) { if(size <= 0){ return; } Node tmp = first; int a = -1; int b = -1; for (int i = 0; i < size; i++) { if((int)tmp.data > min && a == -1){ a = i; } if((int)tmp.data >= max && b == -1){ b = i; } tmp = tmp.next; } if(min < max){ remove(a, b - a); return; } if(min == max){ } if(min > max){ } return; } /** * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * * @param list */ public LinkedList intersection(LinkedList list) { LinkedList result = new LinkedList(); if(list == null || list.size <= 0 || size <= 0){ return result; } int i1 = 0; int i2 = 0; while( i1 < this.size && i2<list.size() ){ int value1 = (int)this.get(i1); int value2 = (int)list.get(i2); if(value1 == value2){ result.add(value1); i1++; i2++; } else if (value1 < value2){ i1++; } else{ i2++; } } return result; } public String toString(){ StringBuffer buffer = new StringBuffer(); buffer.append("["); Node node = first; while(node != null){ buffer.append(node.data); if(node.next != null){ buffer.append(","); } node = node.next; } buffer.append("]"); return buffer.toString(); } }