package collection.concrete;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import static util.TestUtil.*;
import static util.Print.*;
import collection.AbstractList;
import collection.Iterator;
public class LinkedList<E> extends AbstractList<E> {
private Node head;
private int size;
public LinkedList() {
this.head = new Node<E>(null);
this.size = 0;
}
/**
* 把该链表逆置 例如链表为 3->7->10 , 逆置后变为 10->7->3
*/
@SuppressWarnings("unchecked")
public void reverse() {
if (head == null) {
return;
}
Node<E> pre = head;
Node<E> cur = head.next;
Node<E> next;
while (cur != null) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
head.next = null;
head = pre;
}
/**
* 删除一个单链表的前半部分 例如:list = 2->5->7->8 , 删除以后的值为 7->8 如果list = 2->5->7->8->10
* ,删除以后的值为7,8,10
*
*/
public void removeFirstHalf() {
int deleteLength = size / 2;
remove(0, deleteLength);
}
private void clearAndSetNewHead(int deleteIndex) {
Node<E> x = head;
for (int i = 0; i < deleteIndex; i++) {
Node<E> next = x.next;
x.data = null;
x.next = null;
x = next;
size--;
if (i == deleteIndex - 1)
head = next;
}
}
private void clearAndSetNewHead(Node node, int deleteLength) {
Node<E> x = node;
for (int i = 0; i < deleteLength; i++) {
Node<E> next = x.next;
x.data = null;
x.next = null;
x = next;
size--;
if (i == deleteLength - 1)
node = next;
}
}
/**
* 从第i个元素开始, 删除length 个元素 , 注意i从0开始
*
* @param i
* @param length
*/
public void remove(int i, int length) {
checkIndex(i);
checkIndex(i + length);
if (i == 0) {
clearAndSetNewHead(length);
return;
}
Node<E> pre = getNode(i - 1);
Node<E> x = pre.next;
checkIndex(length + i);
for (int j = 0; j < length; j++) {
Node<E> next = x.next;
x.data = null;
x.next = null;
x = next;
size--;
if (i == length - 1)
pre.next = next;
}
}
/**
* 假定当前链表和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<Integer> list) {
if (size() == 0 || list.size() == 0) {
return new int[0];
}
Iterator it2 = list.iterator();
int size = list.size();
int[] result = new int[size];
int curr = (int) it2.next();
Node<E> start = getNode(curr);
result[0] = (int) start.data;
int next, batch;
int res = -1;
for (int i = 1; i < size; i++) {
next = (int) it2.next();
batch = next - curr;
Node<E> p = start;
for (int j = 0; j < batch; j++) {
p = p.next;
}
result[i] = (int) p.data;
start = p;
curr = next;
}
return result;
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 从当前链表中中删除在list中出现的元素
*
* @param list
*/
public void subtract2(LinkedList<E> list) {
LinkedList<E> result = new LinkedList<>();
if (list.size == 0 || this.size == 0) {
return;
}
Node<E> n1 = this.head;
Node<E> n2 = list.head;
Node<E> curr_list = list.head;
for (int i = 0; i < this.size; i++, n1 = n1.next) {
boolean equals = false;
curr_list = list.head;
while(curr_list != null && !equals) {
if (Objects.equals(n1.data, curr_list.data)) {
equals = true;
}
curr_list = curr_list.next;
}
if (!equals) {
result.add(n1.data);
}
}
clearAndSetNewHead(this.size);
Node<E> p2 = result.head;
while(p2.next != null) {
add(p2.data);
p2 = p2.next;
}
add(p2.data);
this.size = result.size;
}
public void subtract(LinkedList<E> list) {
Node<E> n1 = list.getNode(0);
Node<E> n2 = head;
int count = list.size();
int index = 0;
int iR = 0;
while (count != 0 && n1 != null && n2 != null) {
while (count > 1 && Objects.equals(n1.data, n1.next.data)) {
n1 = n1.next;
count--;
}
while (Objects.equals(n1.data, n2.data) == false) {
index++;
if (index > size() - 1)
return;
n2 = n2.next;
}
iR = index;
while (n2 != null && Objects.equals(n1.data, n2.data)) {
remove(iR);
count--;
n2 = n2.next;
}
index = iR;
n1 = n1.next;
}
}
/**
* 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
*/
public void removeDuplicateValues() {
Node<E> n1 = head;
int count = size();
int index = 0;
int iR = 0;
while (count > 1 && n1 != null) {
while (count > 1 && Objects.equals(n1.data, n1.next.data) == false) {
n1 = n1.next;
index++;
count--;
}
iR = index;
while (count > 1 && Objects.equals(n1.data, n1.next.data)) {
remove(iR);
n1 = n1.next;
count--;
}
index = iR;
}
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
*
* @param min
* @param max
*/
public void removeRange(int min, int max) {
if (min >= max) {
throw new IllegalArgumentException(min + " is greater than " + max);
}
if (size() == 0) {
return;
}
Node<E> curr = head;
if ((int) head.data > min) {
curr = curr.next;
}
Node<E> p = head;
while ((int) curr.data <= min) {
p = curr;
curr = curr.next;
}
Node<E> next = curr;
for (Node<E> x = curr; (int) x.data < max;) {
next = x.next;
x.data = null;
x.next = null;
x = next;
size--;
}
if ((int) p.data > min) {
head = next;
size--;
} else {
p.next = next;
}
}
public static void main(String args[]) {
}
/**
* 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
* 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
*
* @param list
*/
public LinkedList<E> intersection(LinkedList<E> list) {
LinkedList<E> result = new LinkedList<E>();
Node<E> n1 = list.getNode(0);
Node<E> n2 = head;
int count = list.size();
int index = 0;
int iR = 0;
while (count != 0 && n1 != null && n2 != null) {
while (Objects.equals(n1.data, n2.data) == false) {
index++;
if (index > size() - 1)
return result;
n2 = n2.next;
}
iR = index;
if (n2 != null && Objects.equals(n1.data, n2.data)) {
result.add(n1.data);
count--;
n2 = n2.next;
}
index = iR;
n1 = n1.next;
}
return result;
}
public void removeDuplicateValues2() {
Node<E> n1 = head;
int count = size();
int index = 0;
int iR = 0;
while (count > 1 && n1 != null) {
while (count > 1 && Objects.equals(n1.data, n1.next.data) == false) {
n1 = n1.next;
index++;
count--;
}
iR = index;
while (count > 1 && Objects.equals(n1.data, n1.next.data)) {
Node<E> next = n1.next.next;
n1.next.data = null;
n1.next = null;
n1 = n1.next;
n1.next = next;
count--;
}
index = iR;
}
}
@Override
public void add(E e) {
addLast(e);
}
@Override
public E get(int index) {
checkIndex(index);
return getNode(index).data;
}
public E getFirst() {
return get(0);
}
public E getLast() {
return get(size - 1);
}
public void add(int index, E e) {
if (index == size) {
addLast(e);
return;
}
if (index == 0) {
addFirst(e);
return;
}
checkIndex(index);
Node<E> pNode = new Node<E>(e);
Node<E> p = getNode(index);
synchronized (this) {
getNode(index - 1).next = pNode;
pNode.next = p;
size++;
}
}
public void addFirst(E e) {
checkCapacity();
Node<E> pNode = new Node<E>(e);
Node oldHead = head;
head = pNode;
pNode.next = oldHead;
size++;
return;
}
public void addLast(E e) {
if (size == 0) {
addFirst(e);
return;
}
checkCapacity();
Node res = new Node<E>(e);
setLastNode(res);
size++;
return;
}
public E removeFirst() {
return remove(0);
}
public E removeLast() {
return remove(size - 1);
}
@SuppressWarnings("unchecked")
public E remove(int index) {
checkIndex(index);
Node<E> pNode = null;
E data = null;
if (index == 0) {
data = (E) head.data;
head = head.next;
} else if (index == size - 1) {
pNode = getNode(index - 1);
data = (E) pNode.next.data;
pNode.next = null;
} else {
pNode = head;
for (int i = 0; i < index - 1; i++) {
pNode = pNode.next;
}
data = (E) pNode.next.data;
pNode.next = pNode.next.next;
}
size--;
return data;
}
@Override
public int size() {
return size;
}
@Override
public Iterator<E> iterator() {
return new LinkedListIterator<E>(this);
}
private void checkCapacity() {
if (size > MAX_SIZE)
throw new IndexOutOfBoundsException("Reached max capacity: " + MAX_SIZE);
}
private Node<E> getNode(int index) {
if (size == 0)
return head;
Node pNode = head;
for (int i = 0; i < index; i++) {
pNode = pNode.next;
}
return pNode;
}
private void setLastNode(Node res) {
getNode(size - 1).next = res;
}
private static class Node<E> {
E data;
Node next;
public Node(E data) {
this.data = data;
this.next = null;
}
@Override
public String toString() {
return data.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data))
return false;
return true;
}
}
@SuppressWarnings("hiding")
private class LinkedListIterator<E> implements Iterator<E> {
private LinkedList<E> myLinkedList;
private int pos;
public LinkedListIterator(LinkedList<E> linkedList) {
myLinkedList = linkedList;
pos = 0;
}
@Override
public boolean hasNext() {
return pos < size;
}
@Override
public E next() {
if (hasNext())
return (E) get(pos++);
throw new NoSuchElementException();
}
}
}