Data structure notes - single linked list and two-way linked list

Posted by ThunderLee on Mon, 13 Dec 2021 15:47:59 +0100

This blog is a learning note written after learning according to the data structure tutorial of Shang Silicon Valley teacher in station b
Some concepts and pictures are from videos. The code and screenshots are done by yourself. The focus of this blog is on the code comments written by yourself
Shang Silicon Valley Java data structure and Java algorithm (Java data structure and algorithm)

Single linked list


A Linked List is a Linked List. The storage method in memory is shown in the figure above

(1) Linked list is stored in the form of nodes, which is chain storage

(2) Each node contains a data field and a next field. The data field is used to save the data to be stored by the current node, and the next field is used to point to the next node

(3) The nodes of the linked list are not necessarily stored continuously

(4) The linked list is divided into the linked list with the leading node and the linked list without the head node, which is determined according to the actual needs

The logical structure diagram of single linked list (leading node) is as follows:

It looks like sequential sequential storage, but it's not. What's the next node is determined by the next domain

Single linked list complete code

Node class, used to create a new node

//Define a HeroNode. Each HeroNode object is a node
class HeroNode{
    public int no;
    public String name;
    public String nickname;
    public HeroNode next; //Point to next node

    public HeroNode(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

Create single linked list

class SingleLinkedList{
    //First initialize a header node. The header node does not store specific data. After initialization, do not modify or move
    private HeroNode head = new HeroNode(0,"","");
}

A complete single linked list should be able to add, delete, modify and query nodes, so
The next step is to add methods such as adding nodes, deleting nodes, modifying nodes and traversing the output to the single linked list class

Add a new node to the end of the single linked list

//Method 1: add nodes to one-way linked list
    //Idea: when the numbering order is not considered, you only need to find the last node of the current linked list, and then let the next of this node point to the new node
    public void add(HeroNode heroNode){
        //Through an auxiliary variable temp to traverse the current linked list, temp is used to point to the current node
        HeroNode temp = head;
        //Traverse the linked list to find the last node
        while(true){
            if(temp.next == null){ //If next is null, the current node pointed to by temp is the last node
                break;
            }
            //If next is not empty, temp points to the node object pointed to by next, so as to achieve the effect of moving temp backward
            temp = temp.next;
        }
        //When exiting the while loop through break, temp points to the last node of the linked list
        //Let the next of this node point to the heroNode object that needs to be added to the linked list
        temp.next = heroNode;
    }

Insert the new node into the specified position by number

 //Method 2: add the node to the single linked list and insert the node into the specified position according to the number no
    //Instead of adding them all to the end of the single linked list as in mode 1
    public void addByNo(HeroNode heroNode){
        //Similarly, use temp to traverse the entire single linked list. Temp is initially equal to head, indicating that the traversal starts from head
        HeroNode temp = head;
        //If the position to be inserted already has a node with the same number no, it will not be inserted
        //A flag of false indicates that there are no duplicate nodes, and a flag of true indicates that there are nodes with duplicate numbers No
        boolean flag = false;
        /*
        temp At the beginning, it points to the head node, and then traverses back. The heroNode is the new node to be inserted
        Take the number of heroNode no and temp Next points to the node number no comparison
        1. temp.next == null,The description has come to the end of the linked list. At this time, it is like method 1 to insert the node at the end of the linked list
        2. temp.next.no < heroNode.no,Then temp continues to traverse backward
        3. temp.next.no == heroNode.no,Setting false to true indicates that there are duplicate nodes
        4. temp.next.no > heroNode.no,Then the current temp The next position is the correct position of the heroNode
        Both cases 1 and 4 indicate that if the insertion position is found, the while loop should be ended to complete the insertion of the new node
         */
        while(true){
            if(temp.next == null){
                break;
            }
            if (temp.next.no > heroNode.no){
                break;
            }
            else if(temp.next.no == heroNode.no){
                flag = true;
                break;
            }
            temp = temp.next; //Let temp move backward to traverse the whole linked list
        }
        if(flag){
            System.out.printf("Number to insert %d Already exists, failed to insert\n",heroNode.no);
        } else {
            //Insert the heroNode after temp, that is, temp Location of next
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }

Modify node

//Modify node
    public void update(HeroNode newHeroNode){
        //Determine whether the linked list is empty
        if(head.next == null){
            System.out.println("The linked list is empty");
        }

        //Find the node to be modified according to the no number
        //Similarly, the temp variable is defined to traverse the linked list
        HeroNode temp = head.next;
        //Judge whether to find the node to be modified. The default value is false. If found, it is true
        boolean flag = false;
        while(true){
            if(temp == null){
                break; //It indicates that all linked lists have been traversed, and the node to be modified has not been found
            }
            if(temp.no == newHeroNode.no){
                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{
            System.out.printf("The number to be modified is %d The node for does not exist\n",newHeroNode.no);
        }
    }

Delete node

//Delete node
    //temp points to the previous node that needs to be deleted
    //When comparing, it is temp next. Comparison between NO and no that needs to delete nodes
    public void del(int no){
        HeroNode temp = head;
        boolean flag = false; //Used to mark whether the node to be deleted is found
        while(true){
            if(temp.next == null){
                //Indicates that the node to be deleted is not found, and the flag is not modified. The default is false
                break;
            }
            if(temp.next.no == no){
                //Only in this case can we find the node to be deleted and set the flag to true
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            temp.next = temp.next.next;
        }else{
            System.out.printf("The number to be deleted is %d The node for does not exist\n",no);
        }
    }

Show all nodes

//Display linked list
    public void list(){
        //First judge whether the linked list is empty
        if(head.next == null){
            System.out.println("The linked list is empty");
        }
        //Similarly, the auxiliary variable temp is used to traverse the entire linked list
        HeroNode temp = head.next;
        while(true){
            //Determine whether the linked list is at the end
            if(temp==null){
                break;
            }
            //Output node information
            System.out.println(temp);
            //temp moves back to the next node
            temp = temp.next;
        }
    }

main function

public static void main(String[] args) {
        //Create node
        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 linked list
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        //Add node to linked list
//        singleLinkedList.add(hero1);
//        singleLinkedList.add(hero2);
//        singleLinkedList.add(hero3);
//        singleLinkedList.add(hero4);

        //Insert nodes out of order
        singleLinkedList.addByNo(hero1);
        singleLinkedList.addByNo(hero3);
        singleLinkedList.addByNo(hero4);
        singleLinkedList.addByNo(hero2);

        //Create a new node
        HeroNode newHeroNode = new HeroNode(2,"Lu","Jade");

        singleLinkedList.update(newHeroNode);

        singleLinkedList.del(4);

        //Display linked list
        singleLinkedList.list();


    }

The final result is

Bidirectional linked list

The bidirectional linked list is different from the unidirectional linked list. Each node of the unidirectional linked list has only one next to point to the next node, while each node of the bidirectional linked list has a pre to point to the previous node and a next to point to the next node.

Image source: http://c.biancheng.net/view/3342.html

Bidirectional linked list code

Create node

//Define a HeroNode. Each HeroNode object is a node
class HeroNode2{
    public int no;
    public String name;
    public String nickname;
    public HeroNode2 next; //Point to next node
    public HeroNode2 pre; //Point to previous node

    public HeroNode2(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

Create a two-way linked list

//Create a two-way linked list
class DoubleLinkedList{
    //Create a header node head
    HeroNode2 head = new HeroNode2(0,"","");
    //Return header node
    public HeroNode2 getHead(){
        return head;
    }
}

Insert the new node at the end of the bidirectional linked list

public void add(HeroNode2 heroNode){
        //Through an auxiliary variable temp to traverse the current linked list, temp is used to point to the current node
        HeroNode2 temp = head;
        while(true){
            if(temp.next == null){
                break;
            }
            temp = temp.next;
        }
        //When exiting the while loop through break, temp points to the last node of the linked list
        //Add the new node to the end of the bidirectional linked list
        temp.next = heroNode;
        heroNode.pre = temp;
    }

Insert the new node into the specified position according to the number

//Insert nodes by number
    public void addByNo(HeroNode2 heroNode){
        HeroNode2 temp = head;
        boolean flag1 = false;
        boolean flag2 = false;
        while(true){
            if(temp.next == null){
                flag2 = true;
                break;
            }
            if(temp.next.no > heroNode.no){
                break;
            }
            if(temp.next.no == heroNode.no){
                flag1 = true;
                break;
            }
            temp = temp.next;
        }
        if(flag1){
            System.out.println("Nodal no Duplicate, insert failed");
        }else{
            if(!flag2){
                temp.next.pre = heroNode;
                heroNode.next = temp.next;
            }
            heroNode.pre = temp;
            temp.next = heroNode;
        }
    }

Modify node

//The node modification method is the same as that in the single linked list, except that the node type is changed
    public void update(HeroNode2 newHeroNode){
        //Determine whether the linked list is empty
        if(head.next == null){
            System.out.println("The linked list is empty");
        }
        HeroNode2 temp = head.next;
        boolean flag = false;
        while(true){
            if(temp == null){
                break;
            }
            if(temp.no == newHeroNode.no){
                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{
            System.out.printf("The number to be modified is %d The node for does not exist\n",newHeroNode.no);
        }
    }

Delete node

//Delete a node from a two-way linked list
    //For a two-way linked list, you only need to find the node to be deleted and delete it by yourself
    public void del(int no){
        //Judge whether the current linked list is empty
        if(head.next == null){
            System.out.println("The current linked list is empty and cannot be deleted");
        }
        //You don't need to find the previous node, so temp can start from head The next node starts traversal, not the head node
        HeroNode2 temp = head.next;
        boolean flag = false; //Used to mark whether the node to be deleted is found
        while(true){
            if(temp == null){
                //Indicates that the node to be deleted is not found, and the flag is not modified. The default is false
                break;
            }
            if(temp.no == no){
                //Only in this case can we find the node to be deleted and set the flag to true
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            //Find the node to be deleted and delete it directly
            temp.pre.next = temp.next;
            //If temp happens to be the last node, the previous sentence is equivalent to temp pre. next = null
            //But temp Next is null. You cannot call the pre pointer with null, so you need to add a judgment
            //When temp is the last node, you don't need to execute the following sentence
            if(temp.next != null){
                temp.next.pre = temp.pre;
            }
        }else{
            System.out.printf("The number to be deleted is %d The node for does not exist\n",no);
        }
    }

Show all nodes

//Display linked list
    public void list(){
        //First judge whether the linked list is empty
        if(head.next == null){
            System.out.println("The linked list is empty");
        }
        //Similarly, the auxiliary variable temp is used to traverse the entire linked list
        HeroNode2 temp = head.next;
        while(true){
            //Determine whether the linked list is at the end
            if(temp==null){
                break;
            }
            //Output node information
            System.out.println(temp);
            //temp moves back to the next node
            temp = temp.next;
        }
    }

main function

 public static void main(String[] args) {
        //Create node
        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.addByNo(hero1);
        doubleLinkedList.addByNo(hero4);
        doubleLinkedList.addByNo(hero2);
        doubleLinkedList.addByNo(hero3);
        doubleLinkedList.list();
}


Although the insertion order is different, the nodes in the final two-way linked list are arranged from small to large in the order of no

Add modify and delete statements

//modify
HeroNode2 newHeroNode = new HeroNode2(4,"Zero charge","No money");
doubleLinkedList.update(newHeroNode);

//delete
doubleLinkedList.del(1);

doubleLinkedList.list();

Topics: Java data structure linked list CRUD