package linkList; /** * 单向链表:其中头结点(head)中没有数据,第一个数据是head结点的下一个结点存贮 * @author 12946 * */ public class LinkedList implements List { private Node head;//头结点 private int size;//链表中元素的个数 public LinkedList(){ this.head = new Node(null); this.size = 0; } public void add(Object o){ Node newNode = new Node(o); Node tempNode = head; while(tempNode.next != null){ tempNode = tempNode.next; } tempNode.next = newNode; size++; } public void add(int index , Object o){ if(index < 0 || index > size-1){ throw new IndexOutOfBoundsException("索引越界"); } Node newNode = new Node(o); Node tempNode = null; if(index == 0){ tempNode = head; }else{ tempNode = getNode(index - 1); } newNode.next = tempNode.next; tempNode.next = newNode; size++; } public Object get(int index){ return getNode(index).data; } public Node getNode(int index){ if(index < 0 || index > size-1){ throw new IndexOutOfBoundsException("索引越界"); } Node tempNode = head; for(int i = -1; i < index; i++){ tempNode = tempNode.next; } return tempNode; } public Object remove(int index){ if(index < 0 || index > size-1){ throw new IndexOutOfBoundsException("索引越界"); } Node tempNode = null; if(index == 0){ tempNode = head; }else{ tempNode = getNode(index - 1); } tempNode.next = tempNode.next.next; size--; return tempNode.next.data; } public int size(){ return size; } public void addFirst(Object o){ Node newNode = new Node(o); newNode.next = getNode(0); head.next = newNode; size++; } public void addLast(Object o){ getNode(size-1).next = new Node(o); size++; } public Object removeFirst(){ if(size < 1){ throw new IndexOutOfBoundsException("链表为null,不能删除元素"); } head.next = head.next.next; size--; return head.next.data; } public Object removeLast(){ if(size < 1){ throw new IndexOutOfBoundsException("链表为null,不能删除元素"); } Object data = null; if(size == 1){ data = head.next.data; head.next = null; }else{ Node tempNode = getNode(size-2); data = tempNode.next.data; tempNode.next = null; } size--; return data; } /** * 根据元素的值查找元素在链表中的位置,找不到则返回-1 * @param o * @return */ public int findIndex(Object o){ for(int i = 0; i < size; i++){ if(get(i).equals(o)){ return i; } } return -1; } public String toString(){ StringBuilder sb = new StringBuilder("["); for(int i = 0; i < size; i++){ sb.append(get(i)); if(i != size-1){ sb.append(","); } } sb.append("]"); return sb.toString(); } private static class Node{ Object data; Node next = null; public Node(Object data){ this.data = data; } } /** * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ int[] arr = new int[size]; for(int i = 0; i < size; i++){ arr[i] = (Integer) get(size - i - 1); } LinkedList newLinkedList = new LinkedList(); for(int i = 0; i < size; i++){ newLinkedList.add(arr[i]); } head = newLinkedList.head; } /** * 删除一个单链表的前半部分 * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf(){ int index = size/2; head.next = getNode(index); size = size - index; } /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * @param i * @param length */ public void remove(int i, int length){ if(i < 0 ){ throw new IndexOutOfBoundsException("索引越界"); } Node startNode = null; Node endNode = null; if(i == 0){ startNode = head; }else{ startNode = getNode(i - 1); } if(i + length >= size){ endNode = null; size = i; }else{ endNode = getNode(i + length); size = size - length; } startNode.next = endNode; } /** * 假定当前链表和listB均包含已升序排列的整数 * 从当前链表中取出那些listB所指定的元素 * 例如当前链表 = 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((Integer)list.get(list.size-1) > this.size - 1){ throw new IndexOutOfBoundsException("list指定的元素角标超过当前链表的范围"); } int[] arr = new int[list.size]; for(int i = 0; i < arr.length; i++){ int index = (Integer) list.get(i); arr[i] = (Integer) this.get(index); } return arr; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 从当前链表中中删除在listB中出现的元素 * @param list */ public void subtract(LinkedList list){ for(int i = 0; i < list.size; i++){ Object value = list.get(i); int index = this.findIndex(value); if(index != -1){ this.remove(index); } } } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues(){ LinkedList newLinkedList = new LinkedList(); for(int i = 0; i < size; i++){ Object value = this.get(i); if(newLinkedList.findIndex(value) == -1){ newLinkedList.add(value); } } this.head = newLinkedList.head; this.size = newLinkedList.size; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * @param min * @param max */ public void removeRange(int min, int max){ int start = 0; int end = size - 1; for(int i = 0; i < size; i++){ int value = (Integer) get(i); if(value <= min){ start++; } } for(int j = size-1; j > -1; j--){ int value = (Integer) get(j); if(value >= max){ end--; } } Node tempNode = null; if(start == 0){ tempNode = head; }else{ tempNode = getNode(start - 1); } tempNode.next = getNode(end).next; size = size - (end - start + 1); } /** * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ public LinkedList intersection( LinkedList list){ LinkedList newLinkedList = new LinkedList(); for(int i = 0; i < list.size; i++){ int value = (Integer) list.get(i); int index = findIndex(value); if(index != -1){ newLinkedList.add(value); } } return newLinkedList; } }