/* * created by Harry 2017-2-21 14:43:41 * 实现简单的LinkedList */ package com.github.HarryHook.coding2017.basic; public class MyLinkedList implements List { private Node head = null; // 头指针 private int size = 0; private static class Node { Object data; Node next; } public void add(Object o) { addLast(o); } // 在指定位置添加元素 public void add(int index, Object o) { if (index > size || index < 0) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } // 存在插入头结点的情况 if (index == 0) { addFirst(o); } else { // 即 index != 0 的情况 // p保存待插入节点的前一节点,x指向要插入的节点 Node x = head; Node p = null; int i = 0; while (i < index) { p = x; x = x.next; i++; } Node n = new Node(); p.next = n; n.next = x; n.data = o; size++; } } // 返回指定位置元素 public Object get(int index) { if (index >= size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } Node x = head; int i = 0; while (i < index && x != null) { x = x.next; i++; } return x.data; } // 移除指定位置节点 public Object remove(int index) { if (index > size || index < 0) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } // 先判断是否是头节点 if (index == 0) { return removeFirst(); } else { Node x = head; Node pre = null; int i = 0; while (i < index) { pre = x; x = x.next; i++; } Object Data = pre.next.data; pre.next = x.next; x = null; size--; return Data; } } // 头部添加节点 public void addFirst(Object o) { Node n = new Node(); n.next = head; head = n; n.data = o; size++; } // 尾部添加节点 public void addLast(Object o) { if (head == null) { head = new Node(); head.data = o; } else { Node x = head; while (x.next != null) { x = x.next; } Node n = new Node(); x.next = n; n.next = null; n.data = o; } size++; } // 移除第一个节点 public Object removeFirst() { Node n = head; Object Data = n.data; head = head.next; n = null; size--; return Data; } // 移除最后一个节点 public Object removeLast() { Node x = head; Node p = null; if (x.next == null) { return removeFirst(); } else { while (x.next != null) { p = x; x = x.next; } Object Data = x.data; p.next = null; x = null; // 删除最后一个节点 size--; return Data; } } public int size() { return size; } public Iterator iterator() { return new MyLinkedListIterator(); } private class MyLinkedListIterator implements Iterator { private int cursor = 0; // 记录索引位置 public boolean hasNext() { return cursor != size; } public Object next() { Object next = get(cursor); cursor++; return next; } } /** * 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3 */ public void reverse() { if (head == null) { return; } Node p1, p2, p3; p1 = head; p2 = p1.next; while (p2 != null) { p3 = p2.next; p2.next = p1; p1 = p2; p2 = p3; } head.next = null; head = p1; } /** * 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10 * ,删除以后的值为7,8,10 * */ public void removeFirstHalf() { if (size == 0) { return; } Node p = head; Node q = null; int i = size / 2; int j = 0; while (j < i) { j++; q = p; p = p.next; } head = p; q.next = null; size = size - i; } /** * 从第i个元素开始, 删除length 个元素 , 注意i从0开始 * * @param i * @param length */ public void remove(int i, int length) { Node p = head; Node q = null; int index = 0; int j = 0; while (index < i) { q = p; p = p.next; index++; } while (p != null && j < length) { p = p.next; j++; } if (i == 0) // 从头开始移除元素 { if (p == null) // 元素全被删光 { head = null; size = 0; } else // 从头删length个元素 { head = p; size = size - length; } } else // 从中间开始移除元素 { if (p == null) { q.next = null; size = size - j; } else { q.next = p; 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(MyLinkedList list) { if (list == null) { return new int[0]; } int i = 0; int[] array = new int[list.size()]; while (i < list.size()) { array[i] = (int) this.get((int) list.get(i)); i++; } return array; } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素 * * @param list */ public void subtract(MyLinkedList list) { int i = 0; if (list == null) { return; } while (i < list.size()) { for (int index = 0; index < this.size(); index++) { Node p = head; // 当前节点 Node q = null; // 前驱节点 while (list.get(i) != p.data && p.next != null) { q = p; p = p.next; } if (p.data == list.get(i)) { // 删除找到的节点 if (p == head) { head = head.next; } else { q.next = p.next; } size--; } } i++; } } /** * 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同) */ public void removeDuplicateValues() { if (head == null) { return; } Node p = head; Node q = head; // 前驱 while (p.next != null) { p = p.next; while (p.data == q.data) { size--; if (p.next == null) { q.next = null; break; } q.next = p.next; p = p.next; if (p == null) break; } q = q.next; } } /** * 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素) * * @param min * @param max */ public void removeRange(int min, int max) { Node p = head; // 当前节点 Node q = head; // 前驱节点 while (p.next != null && ((int) p.data <= min || (int) p.data >= max)) { // 未找到继续遍历 q = p; p = p.next; } while ((int) p.data > min && (int) p.data < max) { // 删除找到的节点 p = p.next; size--; if (size == 0) // 删完所有元素 break; } if (q == head) { // 头结点被删掉 head = p; } else { q.next = p; } } /** * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 * * @param list */ public MyLinkedList intersection(MyLinkedList list) { if (list == null || this == null) { return null; } Node p1 = list.head; Node p2 = this.head; MyLinkedList newList = new MyLinkedList(); while (p1 != null && p2 != null) { while (((int) p1.data < (int) p2.data) && p1.next != null) { p1 = p1.next; } while (((int) p1.data > (int) p2.data) && p2.next != null) { p2 = p2.next; } if (p1.data == p2.data) { newList.add(p1.data); p1 = p1.next; p2 = p2.next; } if (p1 == null && p2 == null) { // 若最后两个元素相等 break; } } return newList; } public static void Print(MyLinkedList myList) { Iterator it = myList.iterator(); System.out.println("对链表中的元素进行打印:"); while (it.hasNext()) System.out.print(it.next() + " "); System.out.println(""); System.out.println("当前元素个数: " + myList.size()); System.out.println(""); } }