package basic.dataStructure.linkedList; import basic.dataStructure.ArrayUtil; import basic.dataStructure.List; import basic.dataStructure.array.ArrayList; /** * Created by macvi on 2017/4/3. */ public class LinkedList implements List { private Node head; public LinkedList() { this.head = new Node(); } public void add(Object o) { if (this.head.data == null) { this.head = new Node(o, null); } else { Node temp = this.head; while (temp.next != null) { temp = temp.next; } temp.next = new Node(o, null); } } public void add(int index, Object o) { if (index > this.size() || index < 0) { throw new IndexOutOfBoundsException(); } if(index == 0){ Node newNode = new Node(o, this.head); this.head = newNode; return; } if(index == this.size()){ this.add(o); return; } Node before = getNode(index - 1); Node next = getNode(index); Node newNode = new Node(o, next); before.next = newNode; } private Node getNode(int index) { int i = 0; Node temp = this.head; while (temp.data != null) { if (index == i) { return temp; } if (temp.next != null) { temp = temp.next; } else break; i++; } return null; } public Object get(int index) { if (index > this.size() || index < 0) { throw new IndexOutOfBoundsException(); } return this.getNode(index).data; } public Object remove(int index) { if(index > this.size() || index < 0){ throw new IndexOutOfBoundsException(); } Object removed = get(index); Node before = getNode(index - 1); Node next = getNode(index + 1); before.next = next; return removed; } public int size() { int size = 0; Node temp = this.head; while (temp.data != null) { size++; if (temp.next != null) { temp = temp.next; } else break; } return size; } public void asList(Object[] array){ LinkedList list = new LinkedList(); for(int i = 0; i < array.length; i++){ list.add(array[i]); } this.head = list.head; } public Object[] toArray(LinkedList list){ int size = list.size(); Object[] arr = new Object[size]; for(int i = 0; i < size; i++){ arr[i] = list.get(i); } return arr; } public String toString() { StringBuffer sb = new StringBuffer(); Node temp = this.head; while (temp.data != null) { sb.append(temp.data.toString()).append(","); if (temp.next != null) { temp = temp.next; } else break; } return sb.toString(); } private static class Node { Object data; Node next; public Node() {} public Node(Object obj, Node next) { this.data = obj; this.next = next; } } /** * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ int size = this.size(); if(size == 1){ return; } Object[] data = new Object[size]; for(int i = 0; i < size; i++){ data[i] = this.get(i); } this.head = new Node(); for(int i = size - 1; i >= 0; i--){ this.add(data[i]); } } /** * 删除一个单链表的前半部分 * 例如:array = 2->5->7->8 , 删除以后的值为 7->8 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf(){ int size = this.size(); int index = this.size()/2; ArrayList al = new ArrayList(); for(int i = index; i < size; i++){ al.add(this.get(i)); } this.head = new Node(); for(int i = 0; i < al.size(); i++){ this.add(al.get(i)); } } /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * @param i * @param length */ public void remove(int i, int length){ for(int j = i; j < i + length; j++){ this.remove(i); } } /** * 假定当前链表和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){ int size = list.size(); int[] arr = new int[size]; for(int i = 0; i < size; i++){ int index = (Integer) list.get(i); arr[i] = (Integer) this.get(index); } return arr; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 从当前链表中中删除在listB中出现的元素 * @param list */ public void subtract(LinkedList list){ Object[] arr1 = toArray(this); Object[] arr2 = toArray(list); for(int i = 0; i < arr2.length; i++){ arr1 = ArrayUtil.remove(arr1, arr2[i]); } asList(arr1); } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues(){ int size = this.size(); ArrayList indexList = new ArrayList(); ArrayList valueList = new ArrayList(); for(int i = 0; i < size; i ++){ int valueI = (Integer)this.get(i); int index = 0; for(int j = i + 1; j < size; j++){ if(valueList.contains(valueI)){ continue; } int valueJ = (Integer) this.get(j); if(valueJ == valueI){ index++; } if(index > 0){ indexList.add(j); valueList.add(valueJ); } } } Object[] arr = new Object[size]; for(int i = 0; i < size; i++){ arr[i] = indexList.contains(i) ? false : this.get(i); } ArrayUtil au = new ArrayUtil(); arr = au.remove(arr, false); asList(arr); } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * @param min * @param max */ public void removeRange(int min, int max){ int size = this.size(); int[] range = new int[max - min]; int index = 0; for(int i = 0; i < size; i++){ int value = (Integer) this.get(i); if(value > min && value < max){ range[index] = value; index++; } } Object[] arr = new Object[size]; for(int i = 0; i < size; i++){ arr[i] = this.get(i); } for(int i = 0; i < range.length; i++){ arr = ArrayUtil.remove(arr, range[i]); } asList(arr); } /** * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ public LinkedList intersection( LinkedList list){ //组合成新的链表 int listSize = list.size(); for(int i = 0 ; i < listSize; i ++){ this.add(list.get(i)); } //转化成数组 int size = this.size(); int[] arr = new int[size]; for(int i = 0; i < size; i++){ arr[i] = (Integer)this.get(i); } //排序 for(int i = 0; i < size - 1; i ++){ for(int j = 0; j < size - i - 1; j ++){ if(arr[j] >= arr[j + 1]){ int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } //组装 LinkedList li = new LinkedList(); for(int i = 0; i < size; i ++){ li.add(arr[i]); } return li; } }