**List implementation class 2 ---------- LinkedList**
When inserting or deleting elements at any position of ArrayList, the subsequent elements need to be moved forward or backward as a whole. The time complexity is O(n) and the efficiency is relatively low. Therefore, another structure is introduced into Java collection: LinkedList, that is, linked list structure;
LinkedList introduction
LinkedList is a common class. The bottom layer adopts a linked List structure. It inherits from AbstractList and implements interfaces such as List, Deque, clonable and Serializable;
LinkedList usage
Two construction methods of LinkedList
Because the underlying structure is a linked list, there is no capacity, so the construction method is one less than ArrayList;
- No parameter construction LinkedList()
List<Integer> list1=new LinkedList<>();
- Use elements in other collections to construct: public LinkedList (Collection <? Extensions E > C)
List<String> al = new ArrayList<>(); al.add("111"); al.add("222"); //Use other container construction List<String> list1=new LinkedList<>(al); System.out.println(list1); //[111, 222]
Common methods for LinkedList
(1) Public Boolean add (e): insert element e at the tail
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); System.out.println(list); //[0000, 1111]
(2) Public void add (int index, e): insert e at the index position
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); list.add(0,"5555"); System.out.println(list); //[5555, 0000, 1111]
(3) Public Boolean addall (collection <? Extensions E > c): insert the element in c at the end
//Insert all the elements in the list into list1 List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); List<String> list1=new LinkedList<>(); list1.addAll(list); System.out.println(list1); //[0000,1111]
(4) public int size(): get the number of valid elements
System.out.println(list.size());
(5) public E remove(int index): deletes the index location element
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); list.remove(1); System.out.println(list); //[0000]
(6) Public Boolean remove (e): deletes the specified element e
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); list.remove("0000"); System.out.println(list);//[1111]
(7) Public Boolean contains (e): whether the element e is included
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); //Include return true System.out.println(list.contains("0000")); //Not included, return false System.out.println(list.contains("9999"));
(8) public E get(int index): get the index location element
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); System.out.println(list.get(1)); //1111
(9) Public e set (int index, e): set the index location element to E
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); list.set(1,"2222"); System.out.println(list);//[0000, 2222]
(10) Public int indexof (E, e): find from front to back and return the subscript of the first e occurrence
List<String> list=new LinkedList(); list.add("0000"); list.add("3333"); list.add(1,"0000"); System.out.println(list.indexOf("0000"));//0
(11) Public int lastIndexOf (E, e): find from back to front and return the subscript of the first e occurrence
List<String> list=new LinkedList(); list.add("0000"); list.add("3333"); list.add(1,"0000"); System.out.println(list.lastIndexOf("0000")); // 1
(12) Public list < E > sublist (int fromindex, int toindex): intercept the [fromIndex,toIndex) part
List<String> list=new LinkedList(); list.add("0000"); list.add("1111"); list.add("2222"); list.add("3333"); list.add("4444"); System.out.println(list.subList(1,4));//[1111, 2222, 3333]
(13) public boolean isEmpty(): determines whether the linked list is empty
System.out.println(list.isEmpty());
(14) public void clear(): clear
list.clear(); System.out.println(list.size()); //0
Traversal of LinkedList
Two traversal modes:
foreach
Iterator traversal
package day20211018; import java.util.List; import java.util.LinkedList; import java.util.ListIterator; public class Test { public static void main(String[] args) { LinkedList<Integer> list = new LinkedList<>(); list.add(1); list.add(2); list.add(3); list.add(4); // foreach traversal for (int e:list) { System.out.print(e + " "); } System.out.println(); // 1 2 3 4 // Iterator traversal ListIterator<Integer> it = list.listIterator(); while(it.hasNext()){ System.out.print(it.next()+ " "); } System.out.println(); //1 2 3 4 } }
Supplement - linked list
Concept of linked list
Physically, linked list is a discontinuous storage structure;
Logically, the logical order of data elements is linked by references in the linked list;
Examples in life: a structure similar to a train
The elements in the linked list are stored in nodes one by one;
The node contains two fields:
Value: the value range of the element in each node
Next: used to point to the next node
It should be noted that each node is an object, and next is only a reference, not an object;
Common structure of linked list
- Unidirectional linked list and bidirectional linked list
One way linked list:
Bidirectional linked list:
- Leading linked list and non leading linked list
No lead node:
Lead node linked list:
- Circular linked list and acyclic linked list
Acyclic linked list:
Circular linked list:
Note: there are 8 structures combined
Linked list implementation
- (1) Simulate the implementation of a single linked list without leading nodes
package day20211018; //Simulation Implementation: single linked list without leading node public class SingleLinkList<E> { public static class Node<E> { E value; Node<E> next; //Construction method public Node(E value) { this.value = value; } } Node<E> head; //Used to point to the first valid node in the linked list //Gets the effective length of the single linked list public int size(){ Node<E> cur=head; int count=0; while(null != cur){ count++; cur=cur.next; } return count; } // Head insert e public void addFirst(E e){ Node<E> newNode=new Node<>(e); if(null==head){ head=newNode; }else{ newNode.next=head; head=newNode; } } // Tail insert e public void addLast(E e) { Node<E> newNode = new Node<>(e); if (null == head) { head = newNode; } else { //Find the last node //cur points to the first node Node<E> cur = head; //pre to mark the position of the last node Node<E> pre = null; while (null != cur) { pre = cur; cur = cur.next; } //Insert new node pre.next = newNode; } } //Insert e at any position, and the first data node is position 0 public boolean addIndex(int position,E e){ //1. Check whether the parameters are legal if(position < 0 || position >= 4){ throw new IllegalArgumentException("Illegal parameter"); } if(0==position){ addFirst(e); return true; } //2. Find the node at position and save the previous one (insert it in front of position) Node<E> cur=head; Node<E> pre=null; while(0 != position){ pre=cur; cur=cur.next; position--; } //3 insert new node Node<E> newNode=new Node<E>(e); newNode.next=cur; pre.next=newNode; return true; } //Delete the node with keyword e for the first time public void remove(E e){ Node<E> cur=head; Node<E> prev=null; //prev is used to mark cur while(null != cur){ if(e.equals(cur.value)){ cur.value=null; if(prev==null){ //Note: the first node is deleted head=cur.next; }else{ //Delete other nodes prev.next=cur.next; } return; } prev=cur; cur=cur.next; } } //Delete all nodes with the value e public void removeAllKey(E e) { //Time complexity O(N^2) /*while(contains(e)){ remove(e); }*/ Node<E> cur=head; Node<E> prev=null; while(null!= cur){ if(e.equals(cur.value)){ //Delete Vertex cur.value=null; if(prev==null){ head=cur.next; cur=head; }else{ prev.next=cur.next; cur=prev.next; } }else{ prev=cur; cur=cur.next; } } } //Find whether to include the keyword e public boolean contains(E e) { Node<E> cur=head; while(null!=cur){ if(e.equals(cur.value)){ return true; } cur=cur.next; } return false; } @Override public String toString(){ Node<E> cur=head; String s="["; while(null!= cur){ s+=cur.value; if(null !=cur.next){ s+=","; } cur=cur.next; } s+="]"; return s; } public static void main(String[] args) { SingleLinkList<Integer> s=new SingleLinkList<>(); System.out.println(s); //[] //Test tail insertion s.addLast(1); s.addLast(2); s.addLast(3); s.addLast(4); System.out.println(s); //[1,2,3,4] System.out.println(s.size()); //4 //Test whether element e is included System.out.println(s.contains(2)); //true System.out.println(s.contains(5)); //false //Test head plug s.addFirst(0); System.out.println(s); //[0,1,2,3,4] //Test insertion anywhere s.addIndex(0,0); System.out.println(s); //[0,0,1,2,3,4] s.addIndex(3,5); System.out.println(s); //[0,0,1,5,2,3,4] //Delete all elements with value 0 s.removeAllKey(0); System.out.println(s); //[1,5,2,3,4] //Test remove s.remove(5); System.out.println(s); //[1,2,3,4] } }
Move your little hand and poke it down~~
Summary - relationship and difference between ArrayList and LinkedList
- Similarities: both implement the List interface;
- The differences are reflected in the following aspects:
(1) Because ArrayList bottom layer uses array to store elements, it supports random access;
(2) The LinkedList bottom layer adopts a two-way linked list structure and does not support random access;
(3) ArrayList supports capacity expansion, but LinkedList does not have the concept of capacity expansion;
(4) In terms of storage space: ArrayList is physically continuous, LinkedList is logically continuous, but physically not necessarily continuous;
(5) When inserting and deleting elements at any position, ArrayList can only be inserted after moving the elements and vacating the position. Therefore, the time complexity is O(N) and the efficiency is slow;
LinkedList only needs to modify the direction of the reference. The time complexity is O(1) and the efficiency is high;
In other words, when efficiently accessing elements, give priority to ArrayList, and * * LinkedList * * *. When inserting and deleting elements at any position