1, General introduction to linked list:
1. single linked list:
Each linked list has a next pointer to the next node and a member to store values
2. Double linked list:
Based on the single linked list, there is also a prev pointer to the previous node.
3. Summary:
(1) Linked lists are stored as nodes
(2) Each node contains the data field, and the next field: points to the next node
(3) Each node of the linked list is not stored continuously
(4) The linked list is divided into header nodes and non header nodes, which are determined according to the actual needs
The data field of the first node is null, and the next field of the tail node is null
2, Single linked list
(1) Add (create)
< 1> First, create a head node to represent the head of the single linked list
< 2> After each node is added, it is directly added to the end of the linked list
//Create node first HeroNode hero1 = new HeroNode(1, "Song Jiang", "Timely rain"); HeroNode hero2 = new HeroNode(2, "Lu Junyi", "Jade Kirin"); HeroNode hero3 = new HeroNode(3, "Wu Yong", "Zhiduoxing"); HeroNode hero4 = new HeroNode(4, "Lin Chong", "Leopard head"); //Create a linked list to SingleLinkList singleLinkList = new SingleLinkList(); //join /**singleLinkList.add(hero1); singleLinkList.add(hero2); singleLinkList.add(hero3); singleLinkList.add(hero4); */ //The second addition method (in order of number) singleLinkList.addByOrder(hero4) ; singleLinkList.addByOrder(hero2) ; singleLinkList.addByOrder(hero3) ; singleLinkList.addByOrder(hero1) ;
(2) Traversal linked list
Because the head node cannot be moved, we need an auxiliary variable to traverse
public void list() { //Determine whether the linked list is empty if (head.next == null) { System.out.println("The linked list is empty"); return; } //Because the head node cannot be moved, we need an auxiliary variable to traverse HeroNode temp = head.next; while(true){ //Determine whether to reach the end of the linked list if( temp == null){ break; } //Output node information (the description has reached the end) System.out.println(temp); //Move temp backward. Be careful temp = temp.next;
(3) Delete node
thinking
1.head cannot be moved, so we need a temp auxiliary variable to find the previous node of the node to be deleted
2. Note that we compare temp.next.no with the node to be deleted
public void del(int no){ HeroNode temp = head; boolean flag = false;//Flag whether the node to be deleted is found while (true) { if(temp.next == null){ //It has reached the end of the linked list break; } if(temp.next.no == no){ //Found the previous node temp of the node to be deleted flag = true; break; } temp = temp.next;//temp backward, traversal } //Judge flag if(flag){//find //Can delete temp.next = temp.next.next; }else{ System.out.println("To delete" +no + "Node does not exist!"); } }
(4) Modify node information
Modify according to the no number. The no number cannot be changed
public void update (HeroNode newHeroNode){ //Judge whether it is empty if(head.next == null){ System.out.println("The linked list is empty"); return; } //Find the number to be modified and number according to no //Define an auxiliary variable HeroNode temp = head.next; boolean flag = false;//Indicates whether the node was found while (true) { if(temp==null){ break;//The linked list has been traversed } if(temp.no == newHeroNode.no){ //find flag = true; break; } temp = temp.next; } //Judge whether to find the node to be modified according to the flag if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; }else{ //Can't find System.out.println("The number was not found" + newHeroNode.no + "Cannot modify!"); } }
(5) Two ways to add nodes to a single linked list
First kind
public void add(HeroNode heroNode) { //Because the head node cannot be moved, we need an auxiliary traversal temp HeroNode temp = head; //Traverse the single linked list to find the last while (true) { //Find the end of the linked list if (temp.next == null) { break; } //If the last is not found, temp will be moved back temp = temp.next; } //When exiting the while loop, temp points to the end of the linked list //Point the next of the last node to the new node temp.next = heroNode; }
Second
public void addByOrder(HeroNode heroNode){ //Because the head node cannot be moved, we still need an auxiliary pointer (variable) to help find the added location //Because of the single linked list, because the temp we are looking for is the previous node in the add auxiliary location, otherwise it cannot be inserted HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null){ //It indicates that temp has reached the end of the linked list break; } if(temp.next.no > heroNode.no ){ //Once the location is found, insert it after temp break; }else if(temp.next.no == heroNode.no){ //Indicates that the number of the heroNode you want to add already exists flag = true;//Description number exists break; } temp = temp.next;//Traverse, move back } //Judge the value of flag if(flag){ //Cannot add, description number exists System.out.println("The number of the hero to insert" + heroNode.no + "Already exists, can't join!"); }else{ //Insert it into the linked list, after temp heroNode.next = temp.next; temp.next = heroNode; } }
(6) Initialize header node
private HeroNode head = new HeroNode(0, "", ""); //Return header node public HeroNode getHead() { return head; }
3. Single chain surface test questions
(1) Gets the number of elements in a single linked list
Method: obtain the number of nodes in the single linked list (if it is the linked list of the leading node, the head node shall not be counted
The head node of the head linked list returns the number of valid nodes
public static int getLength(HeroNode head){ if(head.next == null){ //Empty linked list return 0; }int length = 0; //Define an auxiliary variable HeroNode cur = head.next; while(cur != null){ length++; cur = cur.next;//ergodic } return length; }
(2) Find the penultimate element in the single lin k ed list (Sina)
Idea: 1. Write a method to receive the head node and an index at the same time. 2
2.index indicates that it is the penultimate node
3. Traverse the linked list from beginning to end to get the total length of the linked list getlength
4. After getting the size, we can get it by traversing (getlength - index) from the first one in the linked list
5. If it is found, the node will be returned; otherwise, null will be returned
public static HeroNode findLastIndexNode(HeroNode head,int index){ //If the linked list is empty, null will be returned if(head.next == null){ return null;//Can't find } //The first traversal obtains the length of the linked list (number of nodes) int size = getLength(head); //The second time we traverse the size - index position, it is the penultimate node //First do an index check if(index <=0 || index > size){ return null; } //Define auxiliary variables HeroNode cur = head.next; for (int i = 0; i < size - index; i++) { cur = cur.next; } return cur; }
(3) Reversal of single linked list (Tencent)
public static void reversetList(HeroNode head){ //If the current linked list is empty or there is only one node, there is no need to reverse and return directly if(head.next == null || head.next.next == null){ return ; } //Define an auxiliary variable (pointer) to help us traverse the original linked list HeroNode cur = head.next; HeroNode next = null;//Point to current node [cur] HeroNode reverseHead = new HeroNode(0,"",""); //Traverse the original linked list, traverse each node, take it out and put it at the front of the new linked list reverselist //Difficult while(cur != null){ next = cur.next;//Save the next node of the current node temporarily, because it will be used later cur.next = reverseHead.next;//Point the next node of cur to the front end of the new linked list (connect the two nodes) reverseHead.next = cur;//Connect the head of the new linked list with cur (connect the first line) cur = next;//Move cur back } // head.next = reverseHead.next; }
(4) Print single linked list in reverse order (Baidu)
You can use the stack data structure to push each node into the stack, and then use the first in and last out characteristics of the stack to realize the reverse printing of the single linked list
public static void reversePrint(HeroNode head){ if(head.next == null){ return;//Empty linked list, cannot print } //To create a stack, push each node into the stack Stack<HeroNode>stack = new Stack<HeroNode>(); HeroNode cur = head.next; //Push all nodes of the linked list onto the stack while(cur != null){ stack.push(cur); cur = cur.next;//Move cur backward so that you can push in the next node } //Print the nodes in the stack and pop them out of the stack while(stack.size() > 0){ System.out.println(stack.pop());//stack is characterized by first in and last out } }
4. Overall demonstration of single linked list
package LinkedList; import java.util.Stack; public class SingleLinkedListDemo { public static void main(String[] args) { //Test //Create node first HeroNode hero1 = new HeroNode(1, "Song Jiang", "Timely rain"); HeroNode hero2 = new HeroNode(2, "Lu Junyi", "Jade Kirin"); HeroNode hero3 = new HeroNode(3, "Wu Yong", "Zhiduoxing"); HeroNode hero4 = new HeroNode(4, "Lin Chong", "Leopard head"); //Create a linked list to SingleLinkList singleLinkList = new SingleLinkList(); //join /**singleLinkList.add(hero1); singleLinkList.add(hero2); singleLinkList.add(hero3); singleLinkList.add(hero4); */ //The second addition method (in order of number) singleLinkList.addByOrder(hero4) ; singleLinkList.addByOrder(hero2) ; singleLinkList.addByOrder(hero3) ; singleLinkList.addByOrder(hero1) ; //Test modified code System.out.println("--------------------"); HeroNode newHeroNode = new HeroNode(2,"Xiao Lu","Jade Kirin~~~"); singleLinkList.update(newHeroNode); singleLinkList.list(); /** * If there is a problem, please modify it */ //display System.out.println("-------------------"); singleLinkList.list(); //Delete a node singleLinkList.del(1); System.out.println("Linked list after deletion"); singleLinkList.list(); System.out.println("-------Number of valid nodes in single linked list--------"); System.out.println(getLength(singleLinkList.getHead())); System.out.println("-----------Get the penultimate k Nodes------------"); HeroNode res = findLastIndexNode(singleLinkList.getHead(),2); System.out.println(res); System.out.println("------------Test the reverse function of the single linked list,The structure has changed------------"); reversetList(singleLinkList.getHead()); singleLinkList.list(); System.out.println("------------Print the single linked list in reverse order without changing the linked list structure-------------"); reversePrint(singleLinkList.getHead()); } /**Print single linked list in reverse order*/ //You can use the stack data structure to push each node into the stack, and then use the first in and last out characteristics of the stack to realize the reverse printing of the single linked list public static void reversePrint(HeroNode head){ if(head.next == null){ return;//Empty linked list, cannot print } //To create a stack, push each node into the stack Stack<HeroNode>stack = new Stack<HeroNode>(); HeroNode cur = head.next; //Push all nodes of the linked list onto the stack while(cur != null){ stack.push(cur); cur = cur.next;//Move cur backward so that you can push in the next node } //Print the nodes in the stack and pop them out of the stack while(stack.size() > 0){ System.out.println(stack.pop());//stack is characterized by first in and last out } } /**Reverse single linked list*/ public static void reversetList(HeroNode head){ //If the current linked list is empty or there is only one node, there is no need to reverse and return directly if(head.next == null || head.next.next == null){ return ; } //Define an auxiliary variable (pointer) to help us traverse the original linked list HeroNode cur = head.next; HeroNode next = null;//Point to current node [cur] HeroNode reverseHead = new HeroNode(0,"",""); //Traverse the original linked list, traverse each node, take it out and put it at the front of the new linked list reverselist //Difficult while(cur != null){ next = cur.next;//Save the next node of the current node temporarily, because it will be used later cur.next = reverseHead.next;//Point the next node of cur to the front end of the new linked list (connect the two nodes) reverseHead.next = cur;//Connect the head of the new linked list with cur (connect the first line) cur = next;//Move cur back } // head.next = reverseHead.next; } /**Find the penultimate node in the single lin k ed list*/ //Idea: //1. Write a method to receive the head node and an index at the same time //2.index indicates that it is the penultimate node //3. Traverse the linked list from beginning to end to get the total length of the linked list getlength //4. After getting the size, we can get it by traversing (getlength - index) from the first one in the linked list //5. If it is found, the node will be returned; otherwise, null will be returned public static HeroNode findLastIndexNode(HeroNode head,int index){ //If the linked list is empty, null will be returned if(head.next == null){ return null;//Can't find } //The first traversal obtains the length of the linked list (number of nodes) int size = getLength(head); //The second time we traverse the size - index position, it is the penultimate node //First do an index check if(index <=0 || index > size){ return null; } //Define auxiliary variables HeroNode cur = head.next; for (int i = 0; i < size - index; i++) { cur = cur.next; } return cur; } /** *Method: obtain the number of nodes in the single linked list (if it is the linked list of the leading node, the head node shall not be counted) * @param head Head node of linked list * @return Returns the number of valid nodes */ public static int getLength(HeroNode head){ if(head.next == null){ //Empty linked list return 0; }int length = 0; //Define an auxiliary variable HeroNode cur = head.next; while(cur != null){ length++; cur = cur.next;//ergodic } return length; } } //Define SingleLinkedList to manage our heroes class SingleLinkList { //First initialize a head node. The head node does not move. Do not put specific data (if the head node changes, the whole single linked list will also change!) private HeroNode head = new HeroNode(0, "", ""); //Return header node public HeroNode getHead() { return head; } /**Add node to single linked list*/ //Idea: when the numbering sequence is not considered //1. Find the last node of the current linked list //2. Point the next of the last node to the new node public void add(HeroNode heroNode) { //Because the head node cannot be moved, we need an auxiliary traversal temp HeroNode temp = head; //Traverse the single linked list to find the last while (true) { //Find the end of the linked list if (temp.next == null) { break; } //If the last is not found, temp will be moved back temp = temp.next; } //When exiting the while loop, temp points to the end of the linked list //Point the next of the last node to the new node temp.next = heroNode; } /**The second way is to insert the hero into the specified position according to the ranking when adding the hero*/ // (if there is this ranking, it means that the addition fails and a prompt is given) public void addByOrder(HeroNode heroNode){ //Because the head node cannot be moved, we still need an auxiliary pointer (variable) to help find the added location //Because of the single linked list, because the temp we are looking for is the previous node in the add auxiliary location, otherwise it cannot be inserted HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null){ //It indicates that temp has reached the end of the linked list break; } if(temp.next.no > heroNode.no ){ //Once the location is found, insert it after temp break; }else if(temp.next.no == heroNode.no){ //Indicates that the number of the heroNode you want to add already exists flag = true;//Description number exists break; } temp = temp.next;//Traverse, move back } //Judge the value of flag if(flag){ //Cannot add, description number exists System.out.println("The number of the hero to insert" + heroNode.no + "Already exists, can't join!"); }else{ //Insert it into the linked list, after temp heroNode.next = temp.next; temp.next = heroNode; } } /**Modify the node information according to the no number, and the no number cannot be changed*/ //explain //1. Modify according to the no of newHeroNode public void update (HeroNode newHeroNode){ //Judge whether it is empty if(head.next == null){ System.out.println("The linked list is empty"); return; } //Find the number to be modified and number according to no //Define an auxiliary variable HeroNode temp = head.next; boolean flag = false;//Indicates whether the node was found while (true) { if(temp==null){ break;//The linked list has been traversed } if(temp.no == newHeroNode.no){ //find flag = true; break; } temp = temp.next; } //Judge whether to find the node to be modified according to the flag if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; }else{ //Can't find System.out.println("The number was not found" + newHeroNode.no + "Cannot modify!"); } } /**Delete node*/ //thinking //1.head cannot be moved, so we need a temp auxiliary variable to find the previous node of the node to be deleted //2. Note that we compare temp.next.no with the node to be deleted public void del(int no){ HeroNode temp = head; boolean flag = false;//Flag whether the node to be deleted is found while (true) { if(temp.next == null){ //It has reached the end of the linked list break; } if(temp.next.no == no){ //Found the previous node temp of the node to be deleted flag = true; break; } temp = temp.next;//temp backward, traversal } //Judge flag if(flag){//find //Can delete temp.next = temp.next.next; }else{ System.out.println("To delete" +no + "Node does not exist!"); } } /**Display linked list [traversal]*/ public void list() { //Determine whether the linked list is empty if (head.next == null) { System.out.println("The linked list is empty"); return; } //Because the head node cannot be moved, we need an auxiliary variable to traverse HeroNode temp = head.next; while(true){ //Determine whether to reach the end of the linked list if( temp == null){ break; } //Output node information (the description has reached the end) System.out.println(temp); //Move temp backward. Be careful temp = temp.next; } } } //Define a HeroNode. Each HeroNode object is a node class HeroNode{ public int no; public String name; public String nickname;//nickname public HeroNode next;//Point to next node //Construct a parametric constructor public HeroNode(int no, String name, String nickname) { this.no = no; this.name = name; this.nickname = nickname; } //To display the method, override toString @Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
3, Double linked list
1. Delete node
explain
1. For a two-way linked list, we can directly find the node to be deleted
2. After finding it, delete it by yourself
public void del(int no){ HeroNode2 temp = head.next;//Auxiliary variable (pointer) boolean flag = false;//Flag whether the node to be deleted is found while (true) { if(temp == null){ //It has reached the end of the linked list break; } if(temp.next.no == no){ //Found the previous node temp of the node to be deleted flag = true; break; } temp = temp.next;//temp backward, traversal } //Judge flag if(flag){//find //Can delete //temp.next = temp.next.next; [one way linked list] temp.pre.next = temp.next.next; //If it is the last node, you do not need to execute the following sentence, otherwise a null pointer will appear if(temp.next != null){ temp.next.pre = temp.pre; } }else{ System.out.println("To delete" +no + "Node does not exist!"); } }
2. Modify a node
Modify the node information according to the no number, and the no number cannot be changed
Note 1. Modify according to the no of newHeroNode
public void update (HeroNode2 newHeroNode){ //Judge whether it is empty if(head.next == null){ System.out.println("The linked list is empty"); return; } //Find the number to be modified and number according to no //Define an auxiliary variable HeroNode2 temp = head.next; boolean flag = false;//Indicates whether the node was found while (true) { if(temp==null){ break;//The linked list has been traversed } if(temp.no == newHeroNode.no){ //find flag = true; break; } temp = temp.next; } //Judge whether to find the node to be modified according to the flag if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; }else{ //Can't find System.out.println("The number was not found" + newHeroNode.no + "Cannot modify!"); } }
3. Add node to single double linked list
Idea: when the numbering sequence is not considered
1. Find the last node of the current linked list
2. Point the next of the last node to the new node
Add a node to the end of the linked list
public void add(HeroNode2 heroNode) { //Because the head node cannot be moved, we need an auxiliary traversal temp HeroNode2 temp = head; //Traverse the single linked list to find the last while (true) { //Find the end of the linked list if (temp.next == null) { break; } //If the last is not found, temp will be moved back temp = temp.next; } //When exiting the while loop, temp points to the end of the linked list //Form a two-way linked list temp.next = heroNode; heroNode.pre = temp; }
4. Traverse the double linked list
public void list() { //Determine whether the linked list is empty if (head.next == null) { System.out.println("The linked list is empty"); return; } //Because the head node cannot be moved, we need an auxiliary variable to traverse HeroNode2 temp = head.next; while(true){ //Determine whether to reach the end of the linked list if( temp == null){ break; } //Output node information System.out.println(temp); //Move temp backward. Be careful temp = temp.next; } }
5. Create a double linked list
HeroNode2 hero1 = new HeroNode2(1, "Song Jiang", "Timely rain"); HeroNode2 hero2 = new HeroNode2(2, "Lu Junyi", "Jade Kirin"); HeroNode2 hero3 = new HeroNode2(3, "Wu Yong", "Zhiduoxing"); HeroNode2 hero4 = new HeroNode2(4, "Lin Chong", "Leopard head"); //Create a two-way linked list DoubleLinkedList doubleLinkedList = new DoubleLinkedList(); doubleLinkedList.add(hero1); doubleLinkedList.add(hero2); doubleLinkedList.add(hero3); doubleLinkedList.add(hero4); doubleLinkedList.list();
6. Overall demonstration of double linked list
package LinkedList; public class DoubleLinkedListDemo { public static void main(String[] args) { //test System.out.println("Test of bidirectional linked list"); //Create node first HeroNode2 hero1 = new HeroNode2(1, "Song Jiang", "Timely rain"); HeroNode2 hero2 = new HeroNode2(2, "Lu Junyi", "Jade Kirin"); HeroNode2 hero3 = new HeroNode2(3, "Wu Yong", "Zhiduoxing"); HeroNode2 hero4 = new HeroNode2(4, "Lin Chong", "Leopard head"); //Create a two-way linked list DoubleLinkedList doubleLinkedList = new DoubleLinkedList(); doubleLinkedList.add(hero1); doubleLinkedList.add(hero2); doubleLinkedList.add(hero3); doubleLinkedList.add(hero4); doubleLinkedList.list(); System.out.println("---------------Test the modified linked list-------------"); HeroNode2 newHeroNode = new HeroNode2(4,"Gongsun Sheng","Ru Yunlong"); doubleLinkedList.update(newHeroNode); doubleLinkedList.list(); System.out.println("--------------Delete node-----------"); doubleLinkedList.del(3); doubleLinkedList.list(); } } //Create a bi-directional linked list class class DoubleLinkedList{ //First initialize a head node. The head node does not move. Do not put specific data (if the head node changes, the whole single linked list will also change!) private HeroNode2 head = new HeroNode2(0, "", ""); //Return header node public HeroNode2 getHead() { return head; } //Display linked list [traversal] public void list() { //Determine whether the linked list is empty if (head.next == null) { System.out.println("The linked list is empty"); return; } //Because the head node cannot be moved, we need an auxiliary variable to traverse HeroNode2 temp = head.next; while(true){ //Determine whether to reach the end of the linked list if( temp == null){ break; } //Output node information System.out.println(temp); //Move temp backward. Be careful temp = temp.next; } } //Add node to single double linked list //Idea: when the numbering sequence is not considered //1. Find the last node of the current linked list //2. Point the next of the last node to the new node //Add a node to the end of the linked list public void add(HeroNode2 heroNode) { //Because the head node cannot be moved, we need an auxiliary traversal temp HeroNode2 temp = head; //Traverse the single linked list to find the last while (true) { //Find the end of the linked list if (temp.next == null) { break; } //If the last is not found, temp will be moved back temp = temp.next; } //When exiting the while loop, temp points to the end of the linked list //Form a two-way linked list temp.next = heroNode; heroNode.pre = temp; } //Modify the contents of a node //Modify the node information according to the no number, and the no number cannot be changed //explain //1. Modify according to the no of newHeroNode public void update (HeroNode2 newHeroNode){ //Judge whether it is empty if(head.next == null){ System.out.println("The linked list is empty"); return; } //Find the number to be modified and number according to no //Define an auxiliary variable HeroNode2 temp = head.next; boolean flag = false;//Indicates whether the node was found while (true) { if(temp==null){ break;//The linked list has been traversed } if(temp.no == newHeroNode.no){ //find flag = true; break; } temp = temp.next; } //Judge whether to find the node to be modified according to the flag if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; }else{ //Can't find System.out.println("The number was not found" + newHeroNode.no + "Cannot modify!"); } } //Delete a node from a two-way linked list //explain //1. For a two-way linked list, we can directly find the node to be deleted //2. After finding it, delete it by yourself public void del(int no){ HeroNode2 temp = head.next;//Auxiliary variable (pointer) boolean flag = false;//Flag whether the node to be deleted is found while (true) { if(temp == null){ //It has reached the end of the linked list break; } if(temp.next.no == no){ //Found the previous node temp of the node to be deleted flag = true; break; } temp = temp.next;//temp backward, traversal } //Judge flag if(flag){//find //Can delete //temp.next = temp.next.next; [one way linked list] temp.pre.next = temp.next.next; //If it is the last node, you do not need to execute the following sentence, otherwise a null pointer will appear if(temp.next != null){ temp.next.pre = temp.pre; } }else{ System.out.println("To delete" +no + "Node does not exist!"); } } } //Define a HeroNode. Each HeroNode object is a node class HeroNode2{ public HeroNode2 pre; public int no; public String name; public String nickname;//nickname public HeroNode2 next;//Point to the next node, which is null by default //Construct a parametric constructor public HeroNode2(int no, String name, String nickname) { this.no = no; this.name = name; this.nickname = nickname; } //To display the method, override toString @Override public String toString() { return "HeroNode2{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }