package com.sanmubird.basicDataStructure; import java.util.NoSuchElementException; public class LinkedList implements List { /** 链表:是由节点(Node)组成的, * 而向外暴露的只有一个头节点;我们对链表的所有操作,都是直接或简洁地通过头节点来实现的。 * 节点(Node)是由 一个 存储的对象和一个对下个节点的引用组成的。 * Node中最重要的就是引用了,如果说对ArrayList的增删是ArrayCopy的话,那对LinkedList的增删就是改变引用的指向。 * 因为节点的添加顺序是自右向左的,且最左边的节点是头节点; * 所以,新添加的节点会在左边,而是新添加的节点会成为新的t头节点。 * 头节点可以通过对下一个节点的引用,来找到所有的节点; * 所以:链表里面的属性就有两个,一个是头节点,一个是节点的数量。 ***/ private Node head; //定义一个头节点 private int size ; //节点的数量 public LinkedList(){ this.head = null ; this.size = 0 ; } // 检查输入的参数是否合法 public void argumentCheckForAdd(int index){ if(index > size || index < 0 ){ //这个地反需要验证 index = 0 的情况 throw new IndexOutOfBoundsException("输入的参数超出了边界!"); } } // 检查输入的参数是否合法 public void argumentCheckForOther(int index){ if(index >= size || index < 0 ){ throw new IndexOutOfBoundsException("输入的参数超出了边界!"); } } public Node getHead(){ return head ; } public Object get(int index){ argumentCheckForOther(index); Node node = head ; for(int i = 0 ; i < index ; i++){ node = head.next ; } return node.data; } public int size(){ return size; // return this.size 跟 return size ;有区别没有? } // public void add(Object o){ Node newNode = new Node(o); //实例化一个要添加的节点 if(head == null ){ head = newNode ; }else{ Node temp = head ; while (temp.next != null ){ //这个地方为什么是 temp.next != null ? // 这个地方的作用就是:取出下一个节点;那么当然是在存在下个节点的情况下,才能取出下个节点 temp = temp.next ; // 这样就找到了最后一个节点: temp } temp.next = newNode ; } size++; } // 这个通过画图,然后看图说话就很容易弄出来。 public void add(int index , Object o){ argumentCheckForAdd(index); if(size == index ) add(o); else{ Node preNode = head ; for (int i = 0 ; i < index ; i++){ preNode = preNode.next; } Node nextNode = preNode.next ; Node node = new Node(o); preNode.next = node; node.next = nextNode; size++; } } public Object remove(int index){ argumentCheckForOther(index); Node temp = head ; for(int i = 0 ; i < index ; i++){ temp = temp.next ; } Node removedNode = temp.next ; Node nextNode = removedNode.next ; temp.next = nextNode ; size--; return removedNode.data; } public void addFirst(Object o){ Node node = new Node(o); node.next = head ; head = node ; size++; } public void addLast(Object o){ Node lastNode = head ; while(lastNode.next != null ){ lastNode = lastNode.next ; } Node node = new Node(o); lastNode.next = node ; size++; } public void noSuchElement(){ if(head.next == null){ throw new NoSuchElementException("没有这个元素"); } } public Object removeFirst(){ noSuchElement(); Node node = head.next ; head.next = node.next ; size--; return node.data; } public Object removeLast(){ noSuchElement(); Node temp = head ; for(int i = 0 ; i <size -1 ; i++){ temp = temp.next ; } Node removedNode = temp.next ; temp.next = null ; size--; return removedNode.data; } public Iterator iterator(){ return null; } static class Node{ //此处为什么要使用static来修饰? Object data; //元素域;当前节点存放的元素对象 Node next; //指针域;对一下节点的引用; public Node(Object data){ this.data = data ; this.next = null ; //因为对下一个节点的引用可以为空,所以这个地方可以为空 } } }