package linkedlist;
import java.util.Comparator;
/**
* 实现LinkedList基本功能
* @author Wayss
* 2017-02-23
*/
public class MyLinkedList implements MyList {
private Node head;
private int size = 0;
public void add(Object o){
Node n = new Node(o);
head.next = n;
size++;
}
public void add(int index , Object o){
//1.index校验
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("插入的下标越界了:"+"插入的下标为:"+index+"集合大小为:"+size);
}
//2. 查找index位置的前一个节点
//tempNode为当前链表的第一个节点
Node tempNode = head.next;
for(int i = 0; i < index - 1 ; i++){
tempNode = tempNode.next;
}
Node behindNode = tempNode.next;
Node insertNode = new Node(o);
tempNode.next = insertNode;
insertNode.next = behindNode;
size++;
}
public Object get(int index){
//1.index校验
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("插入的下标越界了:"+"插入的下标为:"+index+"集合大小为:"+size);
}
//2. 查找当前节点
Node tempNode = head.next;
for(int i = 0; i < index; i++){
tempNode = tempNode.next;
}
return tempNode.data;
}
public Object remove(int index){
//1.index校验
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("插入的下标越界了:"+"插入的下标为:"+index+"集合大小为:"+size);
}
//2. 查找当前节点的上一个节点
Node tempNode = head.next;
for(int i = 0; i < index - 1; i++){
tempNode = tempNode.next;
}
Node deleteNode = tempNode.next;
Node behideNode = tempNode.next.next;
tempNode.next = behideNode;
size--;
return deleteNode.data;
}
public int size(){
return size;
}
public void addFirst(Object o){
Node insertNode = new Node(o);
insertNode.next = head.next;
head.next = insertNode;
size++;
}
public void addLast(Object o){
Node insertNode = new Node(o);
Node tempNode = head.next;
for(int i = 0; i < size; i++){
tempNode = tempNode.next;
}
tempNode.next = insertNode;
size++;
}
public Object removeFirst(){
Node firstNode = head.next;
head = firstNode.next;
size--;
return firstNode;
}
public Object removeLast(){
Node tempNode = head.next;
//1.移除需要找到最后一个点的前一个点
for(int i = 0; i < size - 1; i++){
tempNode = tempNode.next;
}
Node deleteNode = tempNode.next;
tempNode.next = null;
size--;
return deleteNode;
}
public MyIterator iterator(){
return new MyLinkedListIterator(this);
}
private class MyLinkedListIterator implements MyIterator{
private MyLinkedList list = null;
private int index = 0;
private MyLinkedListIterator(MyLinkedList list){
this.list = list;
}
@Override
public boolean hasNext(){
if(index < size){
return true;
}
return false;
}
@Override
public Object next(){
return list.get(index++);
}
}
private static class Node{
Object data;
Node next;
public Node(Object data){
this.data = data;
}
}
public void set(int i, Object obj){
remove(i);
add(i,obj);
}
/**
* 把该链表逆置
* 例如链表为 3->7->10 , 逆置后变为 10->7->3
*/
public void reverse(){
//单链表的实现方法,遍历了一遍
//如果是双向链表的话,逆置就简单多了
int half = size/2;
for(int i = 0; i < half; i ++){
Object o1 = get(i);
set(i,o1);
Object o2 = get(size - 1 - i);
set(size - 1 - i, o2);
}
}
/**
* 删除一个单链表的前半部分
* 例如:list = 2->5->7->8 , 删除以后的值为 7->8
* 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
*/
public void removeFirstHalf(){
int half = size/2;
Node tempNode = head.next;
for(int i = 0; i < half; i++){
tempNode = tempNode.next;
}
//通过移动head指针来实现移除前半部分
head.next = tempNode;
}
/**
* 从第i个元素开始, 删除length 个元素 , 注意i从0开始
* @param i
* @param length
*/
public void remove(int i, int length){
if(i < 0 || i > size || i < length || length < 0 || length > size){
return;
}
Node tempNode = head.next;
for(int j = 0; j < i; j++){
tempNode = tempNode.next;
}
Node n1 = tempNode;
for(int j = i; j < length; j++){
tempNode = tempNode.next;
}
Node n2 = tempNode;
//移除n1到n2中间的元素
n1.next = n2;
}
/**
* 假定当前链表和listB均包含已升序排列的整数
* 从当前链表中取出那些listB所指定的元素
* 例如当前链表 = 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 null;
}
Node tempNode = head.next;
Node result = head;
int[] res = new int[list.size()];
for(int j = 0,i = 0; j < size; j++){
if(j == (int)list.removeFirst()){
result.next = tempNode;
res[i++] = (int) tempNode.data;
}else{
tempNode = tempNode.next;
}
}
// return result;
return res;
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 从当前链表中中删除在listB中出现的元素
* @param list
*/
public void subtract(MyLinkedList list){
//方法一
//1.对list递增排序
//2.遍历当前链表,同时和list做比较,向后移动list指针,注意是递增的
//方法二
//1.两层遍历嵌套
for(int i = 0; i < list.size(); i++){
for(int j = 0; j < size; j++){
if(list.get(i).equals(this.get(j))){
this.remove(j);
}
}
}
}
/**
* 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
* 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
*/
public void removeDuplicateValues(){
//1.遍历链表,比较后一个和当前的大小,
//2.相等则,删除后一个,同时再比较原先删除的节点的后一个(可能需要while)
for(int i = 0; i < size; i++){
while(this.get(i).equals(this.get(i+1))){
this.remove(i+1);
//由于remove会把size的大小减一,所以,不会出现数组越界
i++;
//i++的目的是为了判断连续多个值相等的情况
}
}
}
/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 试写一高效的算法,删除表中所有值大于min且小于max的元素(若表中存在这样的元素)
* @param min
* @param max
*/
public void removeRange(int min, int max){
//1.找到第一个值大于min的节点,的前一个节点
//2.找到第一个值小于max的节点
//3.用第一步找出的节点指向第二步找出的节点的next
Node minNode = head.next;
Node maxNode = head.next;
int first = 0;
int last = 0;
//循环停止的条件是,找到了第一个节点不小于min的点了。
//所以,minNode也就没有再往后移动了。即,在不小于min的第一个点的前一个
while((int)this.get(first++) < min){
minNode = minNode.next;
}
while((int)this.get(last++) < max){
maxNode = maxNode.next;
}
//maxNode往后再移动一个位置,表示的是第一个不小于max的点
maxNode = maxNode.next;
minNode.next = maxNode;
}
/**
* 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
* 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列
* @param list
*/
public MyLinkedList intersection( MyLinkedList list){
//1.假设当前链表节点个数是m,list中的节点个数是n
//2.现在需要遍历m+n次,依次把值给链表C传递,同时,给C链表add的时候,注意比较大小
MyLinkedList result = new MyLinkedList();
int i = 0;
int j = 0;
while(i < size){
while(j < list.size()){
if((int)this.get(i) < (int)list.get(j)){
result.add(this.get(i));
i++;
}else if((int)this.get(i) == (int)list.get(j)){
result.add(this.get(i));
i++;
j++;
}else{
result.add(list.get(j));
j++;
}
}
}
return result;
}
}