Single linked list of Java data structure (with detailed drawings, easy to understand)
(this note mainly introduces one-way non leading node acyclic linked list)
It's not easy to sum up. I hope uu you won't be stingy with your work 👍 Yo (^ u ^ ~ yo!!
The linked list is a discontinuous storage structure in the physical storage structure. The logical order of data elements is realized through the reference link order in the linked list. Look at this text. It's not abstract or stiff. Look at the picture below!
🤭 (● ◡ ●) do you see this big gold chain around Fage's neck? In fact, the linked list in the data structure is similar to the gold chain substructure on Fage's neck!!
In practice, the structure of linked list is very diverse. There are many linked list structures when the following situations are combined:
Unidirectional and bidirectional
Take the lead, don't take the lead
Cyclic and non cyclic
Here are some of my sharing experiences around one-way non leading acyclic linked list!!!
In fact, the chain around Fage's neck is composed of sections. So is our single linked list. Each section is a node.
In a node, not only the data but also the address of the next data are stored. In this way, the nodes will be connected one by one. For example, if you want to store a group of data, its structure will be like this
Next, we will implement such a structure through code 😊:
First, make the small rings on the chain, and then string them together
class Node { //A Node exists by creating a Node class public int data; //The value data exists in the node public Node next;//There is a reference (address) of the next node in the node. There may be a question here about the type of next. Let's share it /*Just like when we learn the pointer part of c language, we are defining the type of pointer variable (so c produces everything, in fact, it is the same 😁) int a=10; int*p=&a; p The address of a is stored, and the type of P is determined by A. because a is of type int, the pointer variable p is also of type int ,next The memory stores the reference (address) of the next Node. The Node is Node type, so the next should also be Node type */ public Node (int data){//The constructor initializes the object when instantiating it this.data=data;//this.next will be null by default }
Next is the shining moment of our gold chain! 😎
public class MyLinkedList { public Node head;//head is the reference to the first node public void addFirst(int data); //1. Head insertion method public void addLast(int data); //2. Tail interpolation public void display(); //3. Print single linked list public int size(); //4. Get the length of the single linked list public boolean addIndex(int index,int data); //5. Insert at any position, and the first data node is subscript 0 public boolean contains(int key); //6. Check whether the keyword is included and whether the key is in the single linked list public void remove(int key); //7. Delete the node whose keyword is key for the first time public void removeAllKey(int key); //8. Delete all nodes with the value of key public void clear();//9. Empty the linked list }
The following is the implementation of our interfaces
1. Head insertion method:
public void addFirst(int data) { Node node=new Node(data);//We first create a linked list of the data to be inserted, and then insert it if(this.head==null) {//When there is no data, it is actually directly stored in one data this.head=node;//Then point the head to the node we just created return;//Remember to return directly after completion } node.next=this.head;//Note that the order of the two cannot be reversed (you can try it yourself. If you reverse the linked list, you will not be able to connect). Nodes are connected first to ensure the connection of the linked list this.head=node; }
2. Tail insertion method: (the difficulty is how to find the tail)
public void addLast(int data) { Node node=new Node(data); if(this.head==null) {//If the linked list is empty, insert it directly this.head=node; return; } Node cur=this.head;//Create cur to represent the current node while(cur.next!=null)//Set the loop to let cur go back, and stop the loop when cur reaches the last node { cur=cur.next;//cur backward } cur.next=node;//The last node connects the tail }
3. Print linked list:
public void disPlay() { Node cur=this.head; while (cur!=null) {//Set cycle traversal linked list to complete printing System.out.println(cur.data+" "); cur=cur.next; } }
4. Find the length of the linked list:
public int size() { int count=0; Node cur=this.head; while (cur!=null) {//Traverse the linked list, find the length and return the length count++; cur=cur.next; } return count; }
5. Insertion at the specified location: (the corner mark of the first node is 0, and the one-way linked list is irreversible, so you need to find the location of the previous node at the specified location)
private Node searchIndex(int index) {//Encapsulates a method to find the specified location if(index<0||index>this.size())//Judge location legitimacy { throw new RuntimeException("index Illegal location"); } Node cur=this.head; int count=0; while (count!=index-1)//Find the previous location of the specified location and return this node { count++; cur=cur.next; } return cur; } public void addIndex(int index,int data) { if(index==0) {//Empty linked list direct insertion this.addFirst(data); return; } if(index==this.size()) {//this.size() returns the length of the linked list. The position is the last. The tail interpolation method is called directly this.addLast(data); return; } Node cur=searchIndex(index);//Returns the node of the previous location of the target location Node node=new Node(data);//Create a node for this data node.next=cur.next;//The following two steps are used to complete the connection. Generally, it is connected first and then. If the two steps are changed in sequence, the connection cannot be completed cur.next=node; }
6. Query keyword:
public boolean contains(int key) { if(this.head==null)//Empty linked list directly returns false return false; Node cur=this.head;//cur completes the traversal and queries whether the keyword key exists in the linked list while (cur!=null) { if(cur.data==key) return true; cur=cur.next; } return false;//If it is not found after traversal, false is returned }
7. Delete the first keyword: (because of the irreversibility of the one-way linked list, the previous position of the deleted keyword is returned)
private Node searchDeleteAhead(int key) { Node cur=this.head; while (cur.next!=null) {//Traverse the linked list to find keywords if(cur.next.data==key) {//If found, the reference of the previous node of the keyword is returned return cur; }else { cur=cur.next;//Otherwise, keep walking back } } return null;//Return null not found } public void removeKey(int key) { if(this.head==null) {//Empty linked list returns directly return; } if(this.head.data==key) {//The first node is considered separately because it needs to return the previous node of the keyword. If the header node is a keyword, there is no previous node. You can delete the header node directly this.head=this.head.next; return; } Node ahead=searchDeleteAhead(key); if(ahead==null) { System.out.println("No such node!"); }else { ahead.next=ahead.next.next;//The next of the former node = the next of the deleted node completes the deletion } }
8. Delete all keywords: (delete all keywords through only one traversal)
public void removeAllKeys(int key) { //Because deleting a node requires the connection of the previous node, two nodes need to be established to complete the whole project Node ahead=this.head;//Previous node Node cur=ahead.next;//For the latter node (judge whether data is equal to key in cur), the two nodes traverse back from the beginning while (cur!=null) {//Complete the traversal when cur is empty if(cur.data==key) {//Judge whether the data is equal to the key in cur. If it is equal, delete it ahead.next=cur.next;//Complete the connection first cur=cur.next;//After the connection is completed, move the cur backward and continue to judge the cur Whether data is a keyword, the ahead does not need to be moved (because after the node has been deleted, cur only needs to be moved back, and the ahead is still the previous node of cur) }else {//If they are not equal, both move back ahead=cur; cur=cur.next; } } if(this.head.data==key) {//Finally, consider the head node. If it is equal, delete it this.head=this.head.next; } }
Explain why you finally consider the header node
if(this.head.data==key) { this.head=this.head.next; } while (del!=null) { if(del.data==key) { ahead.next=del.next; del=del.next; }else { ahead=del; del=del.next; } }
As shown in the figure, after deleting the header node first, skip ahead Data, so the head node is considered last. If it is equal, it can be deleted.
9. Empty the linked list:
public void clear() { this.head=null; }
(don't underestimate this line of code. In fact, it completes the emptying of the whole linked list)
When the JVM reclaims memory, the object will be reclaimed only when no one is referencing it When the head is set to null, it is equivalent that no object references the first head node (in fact, it's like all the back of the domino). The first one is recycled and the back is recycled
It's not easy to sum up. I hope uu you won't be stingy with your work 👍 Yo (^ u ^ ~ yo!!