[ArrayList and LinkedList]

Article directory

  • 1.ArrayList
  • 2.LinkedList
    • 2.1 Construction of LinkedList
  • 3. Overall code
  • 4. Test the code

1.ArrayList

We know that List is an interface, and ArrayList is an implementation class of List interface.< /strong>

Because interfaces cannot be instantiated directly, we can let a class implement the interface, and then let this class instantiate a reference object comes out, then this objectacts as a reference to the object of the List interface.

for example:

 List<Integer> list1=new ArrayList<Integer>();

example:

public static void main(String[] args) {<!-- -->
        List<Integer> list=new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        for(int i=0;i<list.size();i + + ){<!-- -->
            System.out.print(list.get(i));//Get the value of i subscript
        }
        System.out.println();
        System.out.println(list.remove(2));
        System.out.println(list.set(0,9));//The return value is the original i subscript value
        System.out.println(list.contains(3));//Determine whether an element is included
    }

List a=new ArrayList();
Then a has all the properties and methods of List, but does not have the unique properties and methods of ArrayList.
a can only call abstract methods in List overridden in ArrayList
If List and ArrayList have the same property c and method void func(). Then a.c calls c in List, because the properties will not be overridden. a.func() calls func() in ArrayList , because ArrayList overrides func() in List.

Explanation, before introducing LinkedList, let’s first talk about the shortcomings of ArrayList:

The bottom layer of ArrayList uses array to store elements, which is a continuous space. When ArrayList inserts or deletes elements at any position, it will involve The time complexity of moving elements is O(N), which is relatively inefficient. Therefore, ArrayList is not suitable for scenarios where there are many elements inserted or deleted at any position. Therefore, we introduced LinkedList (Headless doubly linked list).

2.LinkedList

First of all, we need to know: The bottom layer of LinkedList is a headless doubly linked list structure. LinkedList also implements the List interface.

Construction of nodes in LinkedList:

Since each node has a direct predecessor and direct successor, so any node in the doubly linked list >You can conveniently access its predecessor nodes and successor nodes.

The structure of a simple LinkedList containing 4 nodes:

LinkedListdoes not implement the RandomAccess interface, so LinkedListdoes not support random access.

LinkedList is suitable for scenarios inserted at any position.

Because the linked list does not store elements in continuous space, but stores them in nodes, and then connects the nodes through references, so when inserting or deleting elements at any position, there is no need to move the elements (time The complexity is O(1)) and the efficiency is higher.

2.1 Construction of LinkedList

A doubly linked list is composed of nodes. Let’s first look at the composition of nodes:

public class ListNode {<!-- -->
    public int val;
    public ListNode prev;
    public ListNode next;
    public ListNode(int val){<!-- -->
        this.val=val;
    }
}

We found that each node is composed of three parts, numeric domain, predecessor and successor.

Next let’s look at some basic operations of doubly linked lists (without puppet nodes):

The length of the linked list

public int size(){<!-- -->
        ListNode cur=head;
        int count=0;
        while (cur!=null){<!-- -->
            count + + ;
            cur=cur.next;
        }
        return count;
    }

Print linked list

public void display(){<!-- -->
        ListNode cur=head;
        while(cur!=null){<!-- -->
            System.out.print(cur.val + " ");
            cur=cur.next;
        }
        System.out.println();
    }

Head plug

public void addHead(int data){<!-- -->
        ListNode node=new ListNode(data);
        //If the linked list is empty, directly set head=last=node
        if(size()==0){<!-- -->
            head=node;
            last=node;
        }
        //If the linked list is not empty
        else {<!-- -->
            node.next=head;
            head.prev=node;
            head=node;
        }
    }

Tail plug

public void addTail(int data){<!-- -->
        ListNode node=new ListNode(data);
        //If the linked list is empty, directly set head=last=node
        if(size()==0){<!-- -->
            head=node;
            last=node;
        }else{<!-- -->//When the linked list is not empty
            last.next=node;
            node.prev=last;
            last=node;
        }
    }

Insert element at index subscript

public void add(int index,int data){<!-- -->
        ListNode node=new ListNode(data);
        //First determine whether the index is legal
        if(index<0||index>size()){<!-- -->
            throw new IndexOutOfBoundsException("Array subscript out of bounds");
        }
        //If index==0, it is the head plug
        if(index==0){<!-- -->
            addHead(data);
        } else if (index==size()) {<!-- -->//Tail insertion
            addTail(data);
        }else {<!-- -->
            ListNode cur=head;
            for(int i = 0; i<index; i + + ){<!-- -->
                cur=cur.next;
            }
            cur.prev.next=node;
            node.prev=cur.prev;
            cur.prev=node;
            node.next=cur;
        }
    }

Delete the head node

public void removeHead(){<!-- -->
        //If the linked list is empty, it cannot be deleted
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }
        //The linked list is not empty
        else {<!-- -->
            head=head.next;
        }
    }

Delete the tail node

public void removeTail(){<!-- -->
        //The linked list is empty
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }else {<!-- -->
            last=last.prev;
        }
    }

Delete the first node whose value is key

public void removeKey(int key){<!-- -->
        ListNode cur=head;
        //First determine whether the linked list is empty
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }
        while (cur!=null){<!-- -->
            if(cur.val==key){<!-- -->
                if(cur==head){<!-- -->
                    head=head.next;
                    if(head!=null){<!-- -->
                        head.prev=null;
                    }else {<!-- -->
                        last=null;
                    }
                }else {<!-- -->
                    if(cur.next!=null){<!-- -->
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                    }else {<!-- -->
                        cur.prev.next=cur.next;
                        last=last.prev;
                    }
                }
                return;
            }else {<!-- -->
                cur=cur.next;
            }
        }
    }

Delete all nodes whose value is key

public void removeAll(int key){<!-- -->
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }
        ListNode cur=head;
        while(cur!=null){<!-- -->
            if(cur.val==key){<!-- -->
                if(cur==head){<!-- -->
                    head=head.next;
                    if(head!=null){<!-- -->
                        head.prev=null;
                    }else {<!-- -->
                        last=null;
                    }
                }else {<!-- -->
                    if(cur.next!=null){<!-- -->
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                    }else {<!-- -->
                        cur.prev.next=cur.next;
                        last=last.prev;
                    }
                }
                cur=cur.next;
            }else {<!-- -->
                cur=cur.next;
            }
        }
    }

Clear the linked list

public void clear(){<!-- -->
        ListNode cur=head;
        while (cur!=null){<!-- -->
            ListNode curNext=cur.next;
            cur.prev=null;
            cur.next=null;
            cur=curNext;
        }
        head=null;
        last=null;
    }

3. Overall code

public class LinkedList2 {
    public ListNode head;
    public ListNode last;
    //Get the length of the linked list
    public int size(){<!-- -->
        ListNode cur=head;
        int count=0;
        while (cur!=null){<!-- -->
            count + + ;
            cur=cur.next;
        }
        return count;
    }
    //print linked list
    public void display(){<!-- -->
        ListNode cur=head;
        while(cur!=null){<!-- -->
            System.out.print(cur.val + " ");
            cur=cur.next;
        }
        System.out.println();
    }
    //Head plug
    public void addHead(int data){<!-- -->
        ListNode node=new ListNode(data);
        //If the linked list is empty, directly set head=last=node
        if(size()==0){<!-- -->
            head=node;
            last=node;
        }
        //If the linked list is not empty
        else {<!-- -->
            node.next=head;
            head.prev=node;
            head=node;
        }
    }
    //Tail insert
    public void addTail(int data){<!-- -->
        ListNode node=new ListNode(data);
        //If the linked list is empty, directly set head=last=node
        if(size()==0){<!-- -->
            head=node;
            last=node;
        }else{<!-- -->//When the linked list is not empty
            last.next=node;
            node.prev=last;
            last=node;
        }
    }
    //Insert element at index subscript
    public void add(int index,int data){<!-- -->
        ListNode node=new ListNode(data);
        //First determine whether the index is legal
        if(index<0||index>size()){<!-- -->
            throw new IndexOutOfBoundsException("Array subscript out of bounds");
        }
        //If index==0, it is the head plug
        if(index==0){<!-- -->
            addHead(data);
        } else if (index==size()) {<!-- -->//Tail insertion
            addTail(data);
        }else {<!-- -->
            ListNode cur=head;
            for(int i = 0; i<index; i + + ){<!-- -->
                cur=cur.next;
            }
            cur.prev.next=node;
            node.prev=cur.prev;
            cur.prev=node;
            node.next=cur;
        }
    }
    //Delete the head node
    public void removeHead(){<!-- -->
        //If the linked list is empty, it cannot be deleted
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }
        //The linked list is not empty
        else {<!-- -->
            head=head.next;
        }
    }
    //Delete the tail node
    public void removeTail(){<!-- -->
        //The linked list is empty
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }else {<!-- -->
            last=last.prev;
        }
    }
    //Delete the first node whose value is key
    public void removeKey(int key){<!-- -->
        ListNode cur=head;
        //First determine whether the linked list is empty
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }
        while (cur!=null){<!-- -->
            if(cur.val==key){<!-- -->
                if(cur==head){<!-- -->
                    head=head.next;
                    if(head!=null){<!-- -->
                        head.prev=null;
                    }else {<!-- -->
                        last=null;
                    }
                }else {<!-- -->
                    if(cur.next!=null){<!-- -->
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                    }else {<!-- -->
                        cur.prev.next=cur.next;
                        last=last.prev;
                    }
                }
                return;
            }else {<!-- -->
                cur=cur.next;
            }
        }
    }
    //Delete all nodes whose value is key
    public void removeAll(int key){<!-- -->
        if(size()==0){<!-- -->
            throw new RuntimeException("The linked list is empty and cannot be deleted");
        }
        ListNode cur=head;
        while(cur!=null){<!-- -->
            if(cur.val==key){<!-- -->
                if(cur==head){<!-- -->
                    head=head.next;
                    if(head!=null){<!-- -->
                        head.prev=null;
                    }else {<!-- -->
                        last=null;
                    }
                }else {<!-- -->
                    if(cur.next!=null){<!-- -->
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                    }else {<!-- -->
                        cur.prev.next=cur.next;
                        last=last.prev;
                    }
                }
                cur=cur.next;
            }else {<!-- -->
                cur=cur.next;
            }
        }
    }
    //Clear the doubly linked list
    public void clear(){<!-- -->
        ListNode cur=head;
        while (cur!=null){<!-- -->
            ListNode curNext=cur.next;
            cur.prev=null;
            cur.next=null;
            cur=curNext;
        }
        head=null;
        last=null;
    }
}

4. Test code

public class Test {<!-- -->
    public static void main(String[] args) {<!-- -->
        LinkedList2 linkedList2=new LinkedList2();
        linkedList2.addHead(1);
        linkedList2.addHead(2);
        linkedList2.addHead(3);
        linkedList2.display();
        //3 2 1
        System.out.println("==================");
        linkedList2.add(0,9);
        linkedList2.display();
        //9 3 2 1
        System.out.println("==================");
        linkedList2.removeHead();
        linkedList2.display();
        //3 2 1
        System.out.println("==================");
    }
}