Collection Series-linkedlist Source Analysis
In the last chapter, we analyze the ArrayList implementation, knowing that the ArrayList is based on an array, so it has the feature of quick lookup modification and slow insertion and deletion. This article describes the LinkedList is another implementation of the list interface, its bottom is based on the bidirectional linked list implementation, so it has the insertion delete fast and find changes slow characteristics, in addition, through the two-way linked list operation can also achieve the functions of the queue and stack.
The underlying structure of the LinkedList is shown in the following illustration.
F represents the head node reference, L represents the tail node reference, each node of the linked list has three elements, namely the preceding node reference (P), the value of the node element (E), and the subsequent node reference (N). The node is represented by the internal class node, and we look at its internal structure.
Node Inner class
private Static Class Node<e> {
E item; Elements
Node<e> Next; Next node
Node<e> prev; Previous node
Node (node<e> prev, E element, node<e> next) {
This.item = element;
This.next = Next;
This.prev = prev;
}
}
Node this inner class is actually very simple, there are only three member variables and a constructor, the item represents the value of the node, next is the reference to the next node, Prev is a reference to the previous node, passing through the constructor to the three values. Next look at the LinkedList member variables and constructors.
Number of collection elements
transient int size = 0;
Header node Reference
Transient node<e>;
Tail node Reference
Transient node<e> last;
Non-parametric constructor
Public LinkedList () {}
Constructor for incoming external collection
Public LinkedList (collection<? extends e> c) {
This ();
AddAll (c);
}
LinkedList holds a reference to the head node and a reference to the tail node, which has two constructors, one is an parameterless constructor, and one is a constructor that passes into the external collection. Unlike ArrayList, LinkedList does not specify the initial size of the constructor. Look at its additions and deletions to the search method.
Increase (ADD)
Public boolean Add (E e) {
Add at the end of the list
Linklast (e);
return true;
}
Add (Insert)
public void Add (int index, E element) {
Checkpositionindex (index);
if (index = = size) {
Add at the end of the list
Linklast (Element);
} else {
Insert in the middle of the list
Linkbefore (element, node (index));
}
}
Delete (to set the mark)
Public E-Remove (int index) {
Check to see if the subscript is legal
Checkelementindex (index);
Return unlink (node (index));
}
Delete (given element)
public boolean remove (Object o) {
if (o = = null) {
for (node<e> x = i x!= null; x = X.next) {
if (X.item = = null) {
unlink (x);
return true;
}
}
} else {
Traversing a linked list
for (node<e> x = i x!= null; x = X.next) {
if (O.equals (X.item)) {
If you find it, delete it.
unlink (x);
return true;
}
}
}
return false;
}
Change
Public E Set (int index, E element) {
Check to see if the subscript is legal
Checkelementindex (index);
Gets the node reference for the specified subscript
Node<e> x = node (index);
Gets the value of the specified subscript node
E oldval = X.item;
Set the node element to a new value
X.item = element;
Returns the previous value
return oldval;
}
Check
Public E get (int index) {
Check to see if the subscript is legal
Checkelementindex (index);
Returns the value of the node for the specified subscript
Return node (index). Item;
}
LinkedList's method of adding elements is primarily to invoke Linklast and Linkbefore two methods, linklast by linking an element after the list, linkbefore by inserting an element in the middle of the list. The LinkedList deletion method removes an element from the list by calling the Unlink method. Let's look at the core code for the INSERT and delete operations of the linked list.
Before linking to a specified node
void Linkbefore (e E, node<e> succ) {
Gets the last node reference for a given node
Final node<e> pred = Succ.prev;
Creates a new node, and the previous node reference to the new node points to the last node of the given node
The reference to the next node of the new node points to the given node.
Final node<e> NewNode = new Node<> (pred, E, SUCC);
Points the last node reference to a new node in the given node.
Succ.prev = NewNode;
If the last node of a given node is empty, it indicates that the given node is a head node.
if (pred = = null) {
To point the Head node reference to a new node.
i = NewNode;
} else {
Otherwise, a reference to the next node of the last node of the given node is directed to the new node.
Pred.next = NewNode;
}
Collection element number plus one
size++;
Modify the number of times plus a
modcount++;
}
Unload a specified node
E unlink (node<e> x) {
Gets the elements of a given node
Final E element = X.item;
Gets the reference to the next node of the given node
Final node<e> next = X.next;
Gets the reference to the last node of the given node
Final node<e> prev = X.prev;
If the last node of a given node is empty, the given node is the head node.
if (prev = = null) {
Refers the header node to the next node at the given node
i = next;
} else {
Referring the successor node of the last node to the successor node of the given node
Prev.next = Next;
Empty the last node of a given node
X.prev = null;
}
If the next node of a given node is empty, the given node is a trailing node.
if (next = null) {
References the tail node to the last node of the given node
last = prev;
} else {
Refer the Forward node of the next node to the forward node of the given node
Next.prev = prev;
X.next = null;
}
Empty the elements of a given node
X.item = null;
Set element number minus one
size--;
Modify the number of times plus a
modcount++;
return element;
}
Linkbefore and unlink are representative linking nodes and unloading nodes, and other links and unloading methods are similar to each other, so we will focus on the Linkbefore and unlink methods.
Process diagram of the Linkbefore method: