1. Define nodes (take heroes of hero League as an example)
public int no; // Hero number
public String name; // Hero's name
public String nickName; // Nickname of hero
public HeroNode2 next; // Point to next node
public HeroNode2 pre; // Point to previous node
//Define HeroNode2. Each HeroNode2 object is a node class HeroNode2 { public int no; // Hero number public String name; // Hero's name public String nickName; // Nickname of hero public HeroNode2 next; // Point to next node public HeroNode2 pre; // Point to previous node // constructor public HeroNode2(int no, String name, String nickName) { super(); this.no = no; this.name = name; this.nickName = nickName; } // Override tostring @Override public String toString() { return "HeroNode2 [no=" + no + ", name=" + name + ", nickName=" + nickName + "]"; } }
2. Define bidirectional linked list class
Head node: the front and back nodes of head are empty by default, that is, head next = null; head. pre = null;
class DoubleLinkedList { // First initialize a header node without storing data private HeroNode2 head = new HeroNode2(0, "", ""); }
3. Traversal of bidirectional linked list
It is almost the same as the single linked list!
// Traversing bidirectional 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; } // The head node cannot be moved. We need an auxiliary to traverse temp HeroNode2 temp = head.next; while (true) { // Output node information System.out.println(temp); // If the next linked list is empty if (temp.next == null) { break; } // Move temp back temp = temp.next; } }
4. Addition of bidirectional linked list (added from the tail)
At this time, the auxiliary node temp points to the last node:
/ / when exiting while, temp only thinks about the end of the linked list
/ / when the next and pre of the last node point to the new node
temp.next = heroNode;
heroNode.pre = temp;
// Add data from tail public void add(HeroNode2 heroNode) { // The head node cannot be moved. We need an auxiliary to traverse temp HeroNode2 temp = head; // ergodic while (true) { // Find the end of the linked list if (temp.next == null) { break; } // If you don't find the last temp = temp.next; } // When exiting while, temp only thinks about the end of the linked list // When the next and pre of the last node point to the new node temp.next = heroNode; heroNode.pre = temp; }
5. Addition of two-way linked list (in numbering order)
At this time, temp points to the previous node of the found location:
/ / judge the value of flag. true indicates that flag cannot be added
if (flag) {
System.out.println("the hero number [" + heroNode.no + "] to be inserted has been saved!");
} else {
/ / insert after the linked list
if(temp.next != null) {
temp.next.pre = heroNode;
heroNode.next = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
First judge whether the found location is the last node. If it is the last node, do not run:
temp.next.pre = heroNode;
heroNode.next = temp.next; Prevent null pointer exceptions.
Run if it is not the last node.
Insert nodes sequentially by changing the next pointer of the temp node and the pointer of the newly inserted node.
// Add in ranking order public void addByOrder(HeroNode2 heroNode) { // Because the head node cannot be moved, an auxiliary node is required HeroNode2 temp = head; boolean flag = false; // Whether the number added by the flag exists while (true) { if (temp.next == null) { break; } if (temp.next.no == heroNode.no) { flag = true; break; } if (temp.next.no > heroNode.no) { break; } temp = temp.next; } // Judge the value of flag. true means that it cannot be added if (flag) { System.out.println("Hero number to insert[" + heroNode.no + "]Already saved!"); } else { // Insert after linked list if(temp.next != null) { temp.next.pre = heroNode; heroNode.next = temp.next; } temp.next = heroNode; heroNode.pre = temp; } }
6. Modification of bidirectional linked list
The modification of two-way linked list is the same as that of one-way linked list. You only need to modify the class.
For details, see: Single linked list of data structure
7. Deletion of bidirectional linked list
The auxiliary node temp finds the node to be deleted in the bidirectional linked list, and then the next pointer of the previous node of the node points to the next node of the node. Then judge whether this node is the last node. If it is the last node, make the pre of the next node of this node the previous node of this node. Namely:
temp.pre.next = temp.next;
/ / prevent null pointer exception caused by deleting the last node
if (temp.next != null) {
temp.next.pre = temp.pre;
}
// Delete linked list according to no public void deleteByNo(int no) { if (head.next == null) { System.out.println("No data in linked list"); return; } HeroNode2 temp = head.next; // Define an auxiliary variable boolean flag = false; // Used to determine whether nodes with equal no are found // ergodic while (true) { if (temp == null) { System.out.println("No data in linked list"); break; } if (temp.no == no) { flag = true; break; } temp = temp.next; } // Judge whether the node needs to be deleted according to the flag if (flag) { temp.pre.next = temp.next; // Prevent null pointer exceptions caused by deleting the last node if (temp.next != null) { temp.next.pre = temp.pre; } } else { System.out.println("Not found[" + no + "]This node"); } }
8. Testing
public class DoubleLinkedListDemo { public static void main(String[] args) { System.out.println("Test of bidirectional linked list~~~"); // test HeroNode2 hero1 = new HeroNode2(1, "Lucian", "Holy Lance Ranger"); HeroNode2 hero2 = new HeroNode2(2, "Drizzt", "Card master"); HeroNode2 hero3 = new HeroNode2(3, "Tristana", "Merlin Gunner"); HeroNode2 hero4 = new HeroNode2(4, "Calista", "Spear of revenge"); HeroNode2 hero5 = new HeroNode2(5, "Moffett", "Lava monster"); HeroNode2 hero6 = new HeroNode2(6, "Wayne", "Night hunter"); HeroNode2 hero7 = new HeroNode2(7, "Calsas", "Death chanter"); HeroNode2 hero8 = new HeroNode2(8, "Kasha", "Daughter of the void"); DoubleLinkedList doubleLinkedList = new DoubleLinkedList(); doubleLinkedList.add(hero1); doubleLinkedList.add(hero2); doubleLinkedList.add(hero3); doubleLinkedList.add(hero5); doubleLinkedList.list(); // Add by number System.out.println("Add by number~~~"); doubleLinkedList.addByOrder(hero4); doubleLinkedList.addByOrder(hero6); doubleLinkedList.list(); // modify System.out.println("Modified linked list~~~"); HeroNode2 heroUpdate = new HeroNode2(3, "Skarner ", "Crystal Vanguard "); doubleLinkedList.update(heroUpdate); doubleLinkedList.list(); // delete System.out.println("After deleting the linked list~~~"); doubleLinkedList.deleteByNo(3); doubleLinkedList.list(); } }
9. Overall code
public class DoubleLinkedListDemo { public static void main(String[] args) { System.out.println("Test of bidirectional linked list~~~"); // test HeroNode2 hero1 = new HeroNode2(1, "Lucian", "Holy Lance Ranger"); HeroNode2 hero2 = new HeroNode2(2, "Drizzt", "Card master"); HeroNode2 hero3 = new HeroNode2(3, "Tristana", "Merlin Gunner"); HeroNode2 hero4 = new HeroNode2(4, "Calista", "Spear of revenge"); HeroNode2 hero5 = new HeroNode2(5, "Moffett", "Lava monster"); HeroNode2 hero6 = new HeroNode2(6, "Wayne", "Night hunter"); HeroNode2 hero7 = new HeroNode2(7, "Calsas", "Death chanter"); HeroNode2 hero8 = new HeroNode2(8, "Kasha", "Daughter of the void"); DoubleLinkedList doubleLinkedList = new DoubleLinkedList(); doubleLinkedList.add(hero1); doubleLinkedList.add(hero2); doubleLinkedList.add(hero3); doubleLinkedList.add(hero5); doubleLinkedList.list(); // Add by number System.out.println("Add by number~~~"); doubleLinkedList.addByOrder(hero4); doubleLinkedList.addByOrder(hero6); doubleLinkedList.list(); // modify System.out.println("Modified linked list~~~"); HeroNode2 heroUpdate = new HeroNode2(3, "Skarner ", "Crystal Vanguard "); doubleLinkedList.update(heroUpdate); doubleLinkedList.list(); // delete System.out.println("After deleting the linked list~~~"); doubleLinkedList.deleteByNo(3); doubleLinkedList.list(); } } class DoubleLinkedList { // First initialize a header node without storing data private HeroNode2 head = new HeroNode2(0, "", ""); public HeroNode2 getHead() { return head; } // Add data from tail public void add(HeroNode2 heroNode) { // The head node cannot be moved. We need an auxiliary to traverse temp HeroNode2 temp = head; // ergodic while (true) { // Find the end of the linked list if (temp.next == null) { break; } // If you don't find the last temp = temp.next; } // When exiting while, temp only thinks about the end of the linked list // When the next and pre of the last node point to the new node temp.next = heroNode; heroNode.pre = temp; } // Add in ranking order public void addByOrder(HeroNode2 heroNode) { // Because the head node cannot be moved, an auxiliary node is required HeroNode2 temp = head; boolean flag = false; // Whether the number added by the flag exists while (true) { if (temp.next == null) { break; } if (temp.next.no == heroNode.no) { flag = true; break; } if (temp.next.no > heroNode.no) { break; } temp = temp.next; } // Judge the value of flag. true means that it cannot be added if (flag) { System.out.println("Hero number to insert[" + heroNode.no + "]Already saved!"); } else { // Insert after linked list if(temp.next != null) { temp.next.pre = heroNode; heroNode.next = temp.next; } temp.next = heroNode; heroNode.pre = temp; } } // Delete a node // Delete linked list according to no public void deleteByNo(int no) { if (head.next == null) { System.out.println("No data in linked list"); return; } HeroNode2 temp = head.next; // Define an auxiliary variable boolean flag = false; // Used to determine whether nodes with equal no are found // ergodic while (true) { if (temp == null) { System.out.println("No data in linked list"); break; } if (temp.no == no) { flag = true; break; } temp = temp.next; } // Judge whether the node needs to be deleted according to the flag if (flag) { temp.pre.next = temp.next; // Prevent null pointer exceptions caused by deleting the last node if (temp.next != null) { temp.next.pre = temp.pre; } } else { System.out.println("Not found[" + no + "]This node"); } } // Modify the node information according to no. No cannot be changed 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 node to be modified and number it 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) { // Indicates that the node was found flag = true; break; } temp = temp.next; } // Judge whether it needs to be modified according to the flag if (flag) { temp.name = newHeroNode.name; temp.nickName = newHeroNode.nickName; } else { System.out.println("This node has no data!"); } } // Traversing bidirectional 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; } // The head node cannot be moved. We need an auxiliary to traverse temp HeroNode2 temp = head.next; while (true) { // Output node information System.out.println(temp); // If the next linked list is empty if (temp.next == null) { break; } // Move temp back temp = temp.next; } } } //Define HeroNode2. Each HeroNode2 object is a node class HeroNode2 { public int no; // Hero number public String name; // Hero's name public String nickName; // Nickname of hero public HeroNode2 next; // Point to next node public HeroNode2 pre; // Point to previous node // constructor public HeroNode2(int no, String name, String nickName) { super(); this.no = no; this.name = name; this.nickName = nickName; } // Override tostring @Override public String toString() { return "HeroNode2 [no=" + no + ", name=" + name + ", nickName=" + nickName + "]"; } }