package com.coding.basic; import java.util.NoSuchElementException; import java.util.Objects; public class LinkedList implements List { private Node head; //首节点 private int size; //节点个数 public void add(Object o){ //在链表尾部添加node if(head == null){ head = new Node(o, null); }else { Node last = head; while(last.next != null){ last = last.next; } last.next = new Node(o, null); } size ++; } public void add(int index , Object o){ //在指定索引处插入node if(index > size || index < 0) throw new RuntimeException("IndexOutOfBounds"); if(head == null){ head = new Node(o, null); }else { if(index == 0){ //插入位置在头部 head = new Node(o, head); }else { //后面位置插入 Node temp = head; int i = 0; while(i != index - 1){ temp = temp.next; i ++; } Node tempNext = temp.next; temp.next = new Node(o, tempNext); } } size ++; } public Object get(int index){ //取出指定节点处的元素,从0开始 if(index > size -1 || index < 0) throw new RuntimeException("IndexOutOfBounds"); int i = 0; Node temp = head; while(i != index){ i ++; temp = temp.next; } return temp.data; } public Object remove(int index){ //删除指定索引处的节点 if(index > size -1 || index < 0) throw new RuntimeException("IndexOutOfBounds"); if(index == 0) { //第一个元素或只有一个元素 Object o = head.data; head = head.next; size --; return o; }else { //其他元素 int i = 0; Node temp = head; //被删除节点之前的节点 while(i != index - 1){ i ++; temp = temp.next; } Node delete = temp.next; //被删除的节点 Object o = delete.data; temp.next = delete.next; //删除 size --; return o; } } public int size(){ return size; } public void addFirst(Object o){ //在表头添加节点 head = new Node(o, head); size ++; } public void addLast(Object o){ //在链表尾部添加节点 if(head == null){ head = new Node(o,null); size ++; return; } Node last = head; while(last.next != null){ last = last.next; } last.next = new Node(o, null); size ++; } public Object removeFirst(){ //在链表头部删除节点 if(size() == 0) throw new RuntimeException("Underflow"); Object o = head.data; head = head.next; size --; return o; } public Object removeLast(){ //在链表尾部删除节点 if(size() == 0) throw new RuntimeException("Underflow"); if(size() == 1){ Object o = head.data; head = null; size --; return o; } Node temp = head; int i = 0; while(i != size-2){ temp = temp.next; i ++; } Object o = temp.next.data; temp.next = null; size --; return o; } public Iterator iterator(){ //迭代器 return new ListIterator(); } private class ListIterator implements Iterator{ //实例内部类 private Node current = head; @Override public boolean hasNext() { return current != null; } @Override public Object next() { if(size() == 0) throw new NoSuchElementException("Underflow"); Object o = current.data; current = current.next; return o; } } //这里内部类须为static,在类级别上一一对应,非实例级别 private static class Node{ Object data; Node next; public Node(Object data, Node next) { this.data = data; this.next = next; } } /** * 把该链表逆置 * 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse(){ Node next = null; //当前节点下面一个 Node pre = null; //当前节点前面一个 while(head != null){ next = head.next; head.next = pre; pre = head; head = next; } head = pre; } /** * 删除一个单链表的前半部分 * 例如:list = 2->5->7->8 , 删除以后的值为 7->8 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 */ public void removeFirstHalf(){ if(size() == 0 || size() == 1) return; int half = size()/2; //一半数目 int sum = 0; //已移除总个数 while(sum != half){ head = head.next; sum ++; size --; } } /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * @param i * @param length */ public void remove(int i, int length){ if(length < 0 ) throw new RuntimeException("长度非法"); if(i < 0 || i >= size() || (i+length >size())) throw new RuntimeException("索引越界"); if(i == 0){ int sum = 0; while(sum != length){ head = head.next; sum ++; size --; } return; } Node pre = findNode(i-1); //前一节点 Node next = findNode(i+length); //后一节点 pre.next = next; size -= length; } //查找某个位置的Node private Node findNode(int i){ if(i < 0 ||i > size()) throw new RuntimeException("索引越界"); if(i == size() ) return null; int index = 0; Node temp = head; while(index != i){ temp = temp.next; index ++; } return temp; } /** * 假定当前链表和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){ int sum = list.size(); int[] arr = new int[sum]; for (int i = 0; i < sum; i++) { Integer index = (Integer) list.get(i); Node temp = findNode(index); if(temp == null){ throw new RuntimeException("索引越界"); } arr[i] = (Integer) temp.data; } return arr; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 从当前链表中中删除在list中出现的元素 * @param list */ public void subtract(LinkedList list){ for (int i = 0; i < list.size; i++) { int index = indexOf(list.get(i)); if(index < 0) continue; //没找到相关节点 if(index == 0){ head = head.next; size --; }else { Node pre = findNode(index-1); Node next = findNode(index+1); pre.next = next; size --; } } } //索引对象,返回索引值 private int indexOf(Object o){//返回索引 for (int i = 0; i < size(); i++) { if(Objects.equals(o, get(i))){ //判断两个Object对象是否相等 return i; } } return -1; } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 * 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues(){ if(size() == 0 || size() == 1) return; Node current = head; while(current.next != null){ if(Objects.equals(current.data, current.next.data)){ current.next = current.next.next; size --; }else { current = current.next; } } } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 * 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * @param min * @param max */ public void removeRange(int min, int max){ if(size() == 0) return; if(((Integer)get(0)) >= max ) return; if( ((Integer)get(size()-1)) <= min ) return; if(((Integer)get(0)) <= min && ((Integer)get(size()-1)) < max && ((Integer)get(size()-1)) > min){ for (int i = 1; i < size(); i++) { if(((Integer)get(i)) >min) {findNode(i-1).next = null;size = i;return;} } }else if(((Integer)get(0)) > min && ((Integer)get(0)) < max && ((Integer)get(size()-1)) >= max){ for (int i = 0; i < size(); i++) { if(((Integer)get(i)) >= max){head = findNode(i);size -= 4;return;} } }else if(((Integer)get(0)) <= min && ((Integer)get(size()-1)) >= max){ Node t1=null, t2 =null; int index1=0, index2=0; for (int i = 1; i < size(); i++) { if(((Integer)get(i)) > min){index1 = i;t1 = findNode(i-1);break;} } for (int i = 1; i < size(); i++) { if(((Integer)get(i)) >= max){index2 = i;t2 = findNode(i);break;} } t1.next = t2; size -= (index2-index1); }else { head = null; size = 0; } } /** * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * @param list */ public LinkedList intersection( LinkedList list){ int[] arr1 = new int[this.size()]; int[] arr2 = new int[list.size()]; for (int i = 0; i < this.size(); i++) { Integer num = (Integer) this.get(i); arr1[i] = num; } for (int i = 0; i < list.size(); i++) { Integer num = (Integer) list.get(i); arr2[i] = num; } LinkedList l = new LinkedList(); for (int i = 0; i < arr1.length; i++) { for (int j = 0; j < arr2.length; j++) { if(arr1[i] == arr2[j]){ l.add(arr1[i]); break; } } } return l; } }