package com.coding.basic.homework_03.linkedListImpl;
import com.coding.basic.homework_01.Iterator;
import com.coding.basic.homework_01.List;
/**
* 重新实现的LinkedList
* @author yanght
*
*/
public class LinkedList implements List {
private Node head; //头节点
private Node end; //当前链表的末尾结点
private int num = 0; //链表中元素的个数
/**
* 直接从链表的尾部添加节点
*/
public void add(Object o){
Node node = new Node(o);
if(head == null){ //当前List为空,从第一个节点开始添加
head = end = node;
}else{
end.next = node;
end = node;
}
num++;
}
/**
* 将结点添加到index处(从0开始)
*/
public void add(int index , Object o){
if(index == num){
add(o);
}else if(index < num && index >= 0){
addNode(index, o);
}
}
/**
* 在链表头部和中间添加节点
* @param index
* @param node
*/
private void addNode(int index,Object o){
if(index == 0){
addFirst(o);
}else{
Node node = new Node(o);
Node tem = getNode(index - 1);
Node pos = tem.next;
tem.next = node;
node.next = pos;
num++;
}
}
/**
* 根据索引获取节点
* @param index
* @return
*/
private Node getNode(int index){
Node node = head;
if(index < num){
for(int i = 1; i<= index; i++){
node = node.next;
}
return node;
}
return node;
}
public Object get(int index){
if(index < 0 && index >= num){
throw new IndexOutOfBoundsException();
}
return getNode(index).data;
}
public Object remove(int index){
if(index < 0 && index >= num){
throw new IndexOutOfBoundsException();
}
Object result = null;
if(index == 0){
removeFirst();
}else if(index == num -1){
removeLast();
}else{
Node pre = getNode(index - 1);
result = pre.next.data;
pre.next = pre.next.next;
num--;
}
return result;
}
public int size(){
return num;
}
public void addFirst(Object o){
if(o != null){
Node node = new Node(o);
node.next = head;
head = node;
num++;
}
}
public void addLast(Object o){
add(o);
}
public Object removeFirst(){
Object result = null;
if(size() > 1){
result = head.data;
head = head.next;
num--;
}else if(size() == 1){
result = head.data;
head = end = null;
num-- ;
}
return result;
}
public Object removeLast(){
Object result = null;
if(size() > 1){
Node pre = getNode(num - 2);
result = end.data;
pre.next = null;
end = pre;
num--;
}else if(size() == 1){
result = head.data;
head = end = null;
num-- ;
}
return result;
}
public Iterator iterator(){
return new Iterator(){
private int cur = 0;
private Node node = null;
@Override
public boolean hasNext() {
return num - cur > 0;
}
@Override
public Object next() {
if(node == null){
node = head;
}else{
node = node.next;
}
cur++;
return node.data;
}
};
}
private static class Node{
Object data;
Node next;
@SuppressWarnings("unused")
public Node(){}
public Node(Object data){
this.data = data;
}
}
/**
* 把该链表逆置
* 例如链表为 3->7->10 , 逆置后变为 10->7->3
*/
public void reverse(){
Object[] obj = new Object[num];
Node node = head;
for(int i = obj.length-1; i >= 0; i--){
obj[i] = node.data;
node = node.next;
}
node = head;
for(int i = 0; i < obj.length; i++){
node.data = obj[i];
node = node.next;
}
}
/**
* 删除一个单链表的前半部分
* 例如:list = 2->5->7->8 , 删除以后的值为 7->8
* 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
*/
public void removeFirstHalf(){
Node node = getNode(num / 2);
head = node;
if(num % 2 == 0){
num = num / 2;
}else{
num = num / 2 + 1;
}
}
/**
* 从第i个元素开始, 删除length 个元素 , 注意i从0开始
* @param i
* @param length
*/
public void remove(int i, int length){
if(num - length < i + 1){
throw new IndexOutOfBoundsException();
}
if(num - length == i){ //i后面的全部删除
Node node = getNode(i - 1);
end = node;
num = i;
}else{
Node pre = getNode(i - 1);
Node pos = getNode(i + length);
pre.next = pos;
num = num - length;
}
}
/**
* 假定当前链表和list均包含已升序排列的整数
* 从当前链表中取出那些list所指定的元素
* 例如当前链表 = 11->101->201->301->401->501->601->701
* listB = 1->3->4->6
* 返回的结果应该是[101,301,401,601]
* @param list
*/
public static int[] getElements(LinkedList list, LinkedList listB){
int[] result = new int[listB.size()];
for(int i = 0; i < result.length; i++){
result[i] =(int) list.getNode((Integer)listB.get(i)).data;
}
return result;
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 从当前链表中中删除在list中出现的元素
* @param list
*/
public void subtract(LinkedList list){
for(int i = 0; i < list.size(); i++){
findPos(list.get(i), this);
}
}
/**
* 在原数组中找相同的元素
* @param pos 起始位置
* @param obj 要找的元素
* @param list 原数组
* @return 下一次要传入的位置
*/
private void findPos(Object obj, LinkedList list){
for(int i = 0; i < list.size(); i++){
if(compare(list.get(i), obj) == 0){
list.remove(i);
break;
}
if(compare(list.get(i), obj) > 0){
break;
}
}
}
/**
* 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
* 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
*/
public void removeDuplicateValues(){
int pos = 0;
while(pos < this.size() - 1){
if(compare(this.get(pos), this.get(pos + 1)) == 0){
this.remove(pos);
continue;
}
pos++;
}
}
/**
*比较大小
* @param o1
* @param o2
* @return
*/
private int compare(Object o1, Object o2){
int i1 = (Integer)o1;
int i2 = (Integer)o2;
return i1 > i2 ? 1 : (i1 < i2 ? -1 : 0);
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
* @param min
* @param max
*/
public void removeRange(int min, int max){
Integer start = null;
Integer end = null;
for(int i = 0; i < this.size(); i++){
if(compare(this.get(i), min) > 0 && compare(this.get(i), max) < 0){
if(start == null){
start = end = i;
}else{
end = i;
}
}
}
remove(start, end - start);
}
/**
* 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
* 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
* @param list
*/
public LinkedList intersection( LinkedList list){
int point1 = 0;
int point2 = 0;
LinkedList result = new LinkedList();
while(point1 < this.size() && point2 < list.size()){
if(compare(this.get(point1), list.get(point2)) < 0){
point1++;
}else if(compare(this.get(point1), list.get(point2)) > 0){
point2++;
}else{
result.add(list.get(point2));
point1++;
point2++;
}
}
return result;
}
}