Java custom implementation of linked list LinkedList and sequential list ArrayList

1. The difference between ArrayList and LinkedList
ArrayList : The bottom layer is based on dynamic arrays
. The efficiency of accessing array elements according to the array subscript is the highest, and adding elements to the tail is more efficient.
It is inefficient to delete elements in the array and add data to the array because the array is moved. (In the worst case, to delete the first element, to move the 2nd~n-1 elements, you must move one bit forward.

LinkedList : A dynamic array based on a linked list.
Data deletion and addition are highly efficient, as long as the pointer is changed, but the average efficiency of accessing data is low, and the linked list needs to be traversed.

Summary : For add and remove operations, LinkedList is better than ArrayList because ArrayList needs to move the array.
For random access to get and set, ArrayList is better than Linked List, because LinkedList moves the array.

Second, the main attributes and internal classes in the
ArrayList class 1. Implement the related interface List of ArrayList

public interface List extends Iterable{
    
    
    boolean add(Integer e);
    void add(int index,Integer e);
    //根据下标删除
    Integer remove(int index);
    //删除遇到第一个
    boolean remove(Integer e);
    Integer get(int index);
    Integer set(int index,Integer e);
    int size();
    void clear();
    boolean isEmpty();
    boolean contains(Integer e);
    int indexOf(Integer e);
    int lastIndexOf(Integer e);

2. The main attributes and construction methods in the ArrayList class

package List;
import java.lang.reflect.Array;
import java.util.Arrays;

public class ArrayList implements List {
    
    
    private int[] array;
    private int size;
    //无参数构造方法
    public ArrayList(){
    
    
        array=new int[10];
        size=0;
    }
    //有参数构造方法
    public ArrayList(List other){
    
    
        array=new int[other.size()];
        for(int i=0;i<other.size();i++){
    
    
            array[i]=other.get(i);

        }
        size=other.size();

    }

3. **Add (Add)** element method

public boolean add(Integer e) {
    
    
        //扩容
        if(array.length==size){
    
    
            ensureCapacity(array.length*2);
        }
        //相当于尾插
        array[size++]=e;
        return true;
    }

Add e at the specified position index

public void add(int index, Integer e) {
    
    
        //合法性校验
        if(index<0||index>size){
    
    
            throw new IndexOutOfBoundsException("不合法的下标:"+index);
        }
        //扩容2倍
        if(array.length==size){
    
    
            ensureCapacity(array.length*2);
        }
        //循环实现的效果是一样的
//        for(int i=size;i>index;i--){
    
    
//            array[i]=array[i-1];
//        }
        for(int i=size-1;i>=size;i--){
    
    
            array[i+1]=array[i];
        }
        array[index]=e;
        size++;
    }

4. Find related methods

public Integer get(int index) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标不合法"+index);
        }
        return array[index];
    }

5. Insert related methods

public Integer set(int index, Integer e) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标不合法"+index);
        }
        Integer old=array[index];
        array[index]=e;
        return old;

    }

6. Delete related methods

public Integer remove(int index) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标不合法"+index);
        }
        int e=array[index];
        //从前往后删除
        //[index+1,size-1)的元素搬移到[index,size-2]的位置上
        for(int i=index;i<size;i++){
    
    
            array[i]=array[i+1];
        }
        size--;
        return e;

    }
public boolean remove(Integer e) {
    
    
//        for(int i=0;i<size;i++){
    
    
//            if(array[i]==e){
    
    
//                remove(i);
//                return true;
//            }
//        }
       // return false;
        int index=indexOf(e);
        if(index!=-1){
    
    
            remove(index);
            return true;
        }else{
    
    
            return false;
        }
    }

7. Rewrite the toString method of ArrayList

public String toString() {
    
    
        StringBuilder sb=new StringBuilder("[");
        for(int i=0;i<size;i++){
    
    
            sb.append(array[i]);
            if(i!=size-1){
    
    
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }

8. Other methods (expansion) (Iterator)

public void ensureCapacity(int capacity){
    
    
        //检查是否需要搬家
        if(this.array.length>=capacity){
    
    
            return;
        }
        int[] newArray=new int[capacity];
        //从array数组中搬到newArray数组中
        for(int i=0;i<size;i++){
    
    
            newArray[i]=this.array[i];
        }
        //不再关联老的Array
        this.array=newArray;
    }

Three, the main attributes and internal classes in the LinkedList class
1. Define the Node node

public class Node {
    
    
    public Node prev;
    public Node next;
    public Integer element;
    public Node(Integer element){
    
    
        this.element=element;
    }
}
  1. add related methods
public boolean add(Integer e) {
    
    
        Node newNode=new Node(e);
        if(size==0){
    
    
            this.head=this.last=newNode;
        }else{
    
    
            this.last.next=newNode;
            newNode.prev=this.last;
            this.last=newNode;
        }
        this.size++;
        return true;
    }

Add e at the specified position index:

public void add(int index, Integer e) {
    
    
        if(index<0||index>size){
    
    
            throw new IndexOutOfBoundsException("下标越界"+index);
        }
        if(index==size){
    
    
            //尾插
            add(e);

        }else if(index==0){
    
    
            //头插
            Node newNode=new Node(e);//把值装入结点中
            newNode.next.prev=newNode;
            this.head=newNode;
            size++;
        }else{
    
    
            //其他情况
            //找到Index-1所在的位置,进行结点的插入
            Node prev;
            if(index-1<size/2){
    
    
                prev=head;
                for(int i=0;i<index-1;i++){
    
    
                    prev=prev.next;
                }
            }else{
    
    
                prev=last;
                for(int i=0;i<size-index;i++){
    
    
                    prev=prev.prev;
                }
            }
            //走到这里,prev指向index-1位置的下标
            Node next=prev.next;
            Node newNode=new Node(e);
            newNode.prev=prev;
            newNode.next=next;
            prev.next=newNode;
            next.prev=newNode;
            size++;
        }
    }

3. Remove related methods

 public Integer remove(int index) {
    
    
        if(index<0||index>=size){
    
    
            throw new IndexOutOfBoundsException("下标越界"+index);
        }
        //走到这里,下标一定是>0的
        Integer v;
        if(index==0){
    
    
            v=head.element;
            this.head=this.head.next;
            this.head.prev=null;
            size--;
            if(size==0){
    
    
                last=null;
            }
        }else if(index==size-1){
    
    
            v=last.element;
            this.last=this.last.prev;
            this.last.next=null;
            size--;
            if(size==0){
    
    
                head=null;
            }
        }else{
    
    
            Node prev;
            if(index-1<size/2){
    
    
                prev=head;
                for(int i=0;i<index-1;i++){
    
    
                    prev=prev.next;
                }
            }else {
    
    
                prev=last;
                for(int i=0;i<size-index;i++){
    
    
                    prev=prev.prev;
                }
            }
            Node toRemove=prev.next;
            v=toRemove.element;
            prev.next=toRemove.next;
            toRemove.next.prev=prev;
            size--;
        }
        return v;
    }

4. Other methods

public boolean isEmpty() {
    
    
        return size==0;
    }
public boolean contains(Integer e) {
    
    
        return indexOf(e)!=-1;
    }
public int indexOf(Integer e) {
    
    
        int i=0;
        for(Node cur=head;cur!=null;cur=cur.next,i++){
    
    
            if(cur.element.equals(e)){
    
    
                return i;
            }
        }
        return -1;
    }
public int lastIndexOf(Integer e) {
    
    
        int i=size-1;
        for(Node cur=last;cur!=null;cur=cur.prev,i--){
    
    
            if(cur.element.equals(e)){
    
    
                return i;
            }
        }
        return -1;
    }
 public Iterator iterator() {
    
    
        return new LinkedListIterator(this);
    }

Guess you like

Origin blog.csdn.net/m0_46551861/article/details/108721161