Bidirectional linked list of data structure

Posted by greggustin on Sun, 26 Dec 2021 08:21:43 +0100

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 + "]";
	}

}

Topics: Java data structure linked list