package cn.net.pikachu.basic;
import java.util.NoSuchElementException;
import java.util.Objects;
public class LinkedList implements List {
private Node head;
private int curSize = 0;
private class Itr implements Iterator {
Node curNode = head;
@Override
public boolean hasNext() {
return curNode != null;
}
@Override
public Object next() {
Node node = curNode;
curNode = curNode.next;
return node.data;
}
}
public void add(Object o) {
if (head == null) {
head = new Node(o, null);
} else {
Node node = head;
while (node.next != null) {
node = node.next;
}
node.next = new Node(o, null);
}
curSize++;
}
public void add(int index, Object o) {
// 这里可以等于
if (index < 0 || index > curSize) {
throw new IndexOutOfBoundsException(String.valueOf(index));
}
if (index == 0) {
addFirst(o);
} else {
Node node = head;
for (int i = 1; i < index; i++) {
node = node.next;
}
node.next = new Node(o, node.next);
curSize++;
}
}
public Object get(int index) {
if (index < 0 || index >= curSize) {
throw new IndexOutOfBoundsException(String.valueOf(index));
}
Node node = head;
for (int i = 0; i < index; i++) {
node = node.next;
}
return node.data;
}
public Object remove(int index) {
if (index < 0 || index >= curSize) {
throw new IndexOutOfBoundsException(String.valueOf(index));
}
if (index == 0) {
Object o = head.data;
head=head.next;
curSize--;
return o;
}
Node node = head;
for (int i = 1; i < index; i++) {
node = node.next;
}
Node t = node.next;
node.next=t.next;
curSize--;
return t.data;
}
public int size() {
return curSize;
}
public void addFirst(Object o) {
Node node = new Node(o, head);
head = node;
curSize++;
}
public void addLast(Object o) {
add(o);
}
public Object removeFirst() {
if (head == null) {
throw new NoSuchElementException();
}
Node node = head;
head = head.next;
curSize--;
return node.data;
}
public Object removeLast() {
if (head == null) {
throw new NoSuchElementException();
}
Node node;
if (head.next == null) {
node = head;
head = null;
} else {
node = head;
while (node.next.next != null) {
node = node.next;
}
Node t = node.next;
node.next = null;
node = t;
}
curSize--;
return node.data;
}
// 后面再实现
public Iterator iterator() {
return new Itr();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("[");
Node node = head;
while (node != null) {
builder.append(node.data).append(",");
node = node.next;
}
if (curSize>0)
builder.deleteCharAt(builder.length() - 1);
builder.append("]");
return builder.toString();
}
private static class Node {
Object data;
Node next;
Node(Object data, Node next) {
this.data = data;
this.next = next;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
", next=" + next +
'}';
}
}
/**
* 把该链表逆置
* 例如链表为 3->7->10 , 逆置后变为 10->7->3
*/
public void reverse(){
if (head == null){
return;
}
Node node = head;
head=head.next;
node.next=null;
while (head!=null){
Node t = head;
head= head.next;
t.next=node;
node=t;
}
head=node;
}
/**
* 删除一个单链表的前半部分
* 例如:list = 2->5->7->8 , 删除以后的值为 7->8
* 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
*/
public void removeFirstHalf(){
int count = (curSize)/2;
for (int i = 0; i < count; i++) {
head=head.next;
}
}
/**
* 从第i个元素开始, 删除length 个元素 , 注意i从0开始
* @param i
* @param length
*/
public void remove(int i, int length){
if (length<=0){
throw new IllegalArgumentException("length = "+length);
}
if (i+length > size()){
throw new IndexOutOfBoundsException(String.valueOf(i+length));
}
if (i==0){
for (int j = 0; j < length; j++) {
head=head.next;
}
return;
}
Node node = head;
for (int j = 1; j < i; j++) {
node=node.next;
}
for (int j = 0; j < length; j++) {
if (node.next!=null){
node.next=node.next.next;
}
}
}
/**
* 假定当前链表和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 (list==null){
return null;
}
if (list.size()==0){
return new int[0];
}
int[] a = new int[list.size()];
int curIndex = 0;
Node curNode = head;
for (int i = 0; i < list.size(); i++) {
int index = (int) list.get(i);
while (curIndex<index){
curIndex++;
curNode=curNode.next;
}
a[i]= (int) curNode.data;
}
return a;
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 从当前链表中中删除在listB中出现的元素
* @param list
*/
public void subtract(LinkedList list){
if (list==null || list.size()==0){
return;
}
int curIndex = 0;
int i = 0;
while (i<list.size()) {
// 没有实现Comparable比较难办 下次写成泛型好了
// 这次默认只比较整数
int a = (int) get(curIndex);
int b = (int) list.get(i);
if (Objects.equals(a,b)){
remove(curIndex);
}else if (a<b){
curIndex++;
}else if (a>b){
i++;
}
}
}
/**
* 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
* 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
*/
public void removeDuplicateValues(){
Node node = head;
Node tempHead = node;
Node t = tempHead;
while (node.next!=null){
node=node.next;
if (!Objects.equals(node.data,t.data)){
t.next=node;
t=t.next;
}
}
t.next=null;
head=tempHead;
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
* @param min
* @param max
*/
public void removeRange(int min, int max){
if (min>=max){
throw new IllegalArgumentException("min = "+min+", max = "+max);
}
int curIndex = 0;
Node node = head;
while (curIndex<size()){
if ((int)node.data>min && (int)node.data<max){
node=node.next;
remove(curIndex);
}else {
curIndex++;
node=node.next;
}
}
}
/**
* 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
* 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
* @param list
*/
public LinkedList intersection( LinkedList list){
if (list==null){
return null;
}
if (list.size()==0){
System.out.println("0");
return new LinkedList();
}
LinkedList l = new LinkedList();
int i=0;
int j=0;
while (i<size() && j<list.size()){
int a = (int) get(i);
int b = (int) list.get(j);
if (a == b){
l.add(a);
i++;
j++;
}else if (a<b){
i++;
}else {
j++;
}
}
return l;
}
}