Java linked list|The difference between head pointer and virtual head node

A one-way linked list is connected by nodes one by one. The node actually stores the data. The node contains a piece of data and a pointer to the next node.
In the Java language one-way linked list environment, what is the difference between the use of the head pointer and the virtual head node?
insert image description here

The head pointer points to a null (that is Node head = null), a node that does not exist, and the linked list
is empty at this time; the virtual head node actually exists, but the element it stores is empty, and the next node it points to is also empty.

Once the virtual head node is set up, all nodes in the entire linked list will have a predecessor node. In this way, it will become simple and uniform for us to perform addition, deletion, modification, and query at any position. If the virtual head node is not set but the head pointer is used, the operation of if-else logic judgment is required.

For example, write a simple java file to implement and only implement the element operation of adding (inserting in order) strings.
In this java file, write and implement two methods of inserting linked list elements:

  • Use the head pointer to implement the element insertion of the linked list;
  • Use the virtual head node to realize the element insertion of the linked list;
/**这里自定义一个链表,仅实现了添加(按照顺序插入)字符串的元素操作 */
public class LinekedList {
    
    

    private Node<String> head;/**头指针*/

    /** 按照顺序依次添加-使用头指针实现链表的元素插入*/
    public void addElement(String value) {
    
    
        Node<String> node = new Node<>(value);
        if (head == null) {
    
    
            node.next = head; // 将node插入到head的前面,完成插入。
            head = node; // 移动head指针到node上(将node作为新的非空head指针)为后续插入做准备。
        } else {
    
    
            node.next = head.next; // 将node指针指向head的后驱节点
            head.next = node; // 将head指针指向node节点,完成插入。

            head = node; // 移动head指针移动到新插入的node节点上,为后续插入做准备。
            // (即将原先指向非空head节点的指针改换指向到node节点上,将node节点作为新的非空头指针)
        }
    }


    /**虚拟头结点*/
    private Node<String> dummyHead = new Node<>(null,null);

    /** 按照顺序依次添加-使用虚拟头结点实现链表的元素插入 */
    public void fillElement(String value) {
    
    
        Node<String> node = new Node<>(value);
        node.next = dummyHead.next; // 将node指针指向dummyHead的后驱节点
        dummyHead.next = node; // 将dummyHead指针指向node节点,完成插入。

        dummyHead = node; // 移动dummyHead指针到新插入的node节点上,为后续插入做准备。
        // (即将原先指向dummyHead的指针改换指向到node节点上,将node节点作为新的虚拟头结点)
    }
	/**虚拟头结点*/
    private Node<String> dummyHeader = new Node<>(null,null);

    /**按照下标插入*/
    public void fillElement(int index, String value) {
    
    
        Node<String> dummyHeaderTemp = dummyHeader;
        while(index-- > 0) {
    
    
            dummyHeader = dummyHeader.next; // 获取到所要添加节点位置的前驱节点
            // (其实就是移动指向虚拟头结点的指针到所要添加节点位置的前驱节点,
            // 然后将该前驱节点作为新的虚拟头结点,此时新的虚拟头结点data和next都非空)
        }

        Node<String> node = new Node<>(value);
        node.next = dummyHeader.next; // 将node指针指向dummyHeader的后驱节点
        dummyHeader.next = node; // 将dummyHeader指针指向node节点,从而完成插入。

        dummyHeader = dummyHeaderTemp; // 将dummyHeader指针指向原虚拟头结点dummyHeader
        // 目的是,再次以下标插入时仍然以虚拟头结点作为开始。
    }
    
    class Node<E> {
    
    
        private E data;
        public Node next;
        public Node(E data){
    
    
            this.data = data;
        }
        public Node(E data, Node<E> next) {
    
    
            this.data = data;
            this.next = next;
        }
    }
}

Advantages of linked list~

  • The linked list can flexibly allocate memory space;
  • Elements can be deleted or added in O(1) time, provided that the previous element of the element is known. Of course, it also depends on whether it is a single-linked list or a double-linked list. In a double-linked list, if the next element of the element is known, the same The element can be removed or added in O(1) time.

Disadvantages of linked list~

  • Unlike arrays, which can quickly read elements through subscripts, they must be read one by one from the head of the linked list every time;
  • Querying the kth element takes O(k) time.

Application scenario: If many of the problems encountered require quick query, the linked list may not be suitable; if the number of data elements is uncertain in the encountered problems, and data needs to be added and deleted frequently, then the linked list will be more suitable . However, if the size of the data elements is determined and there are not many deletion and insertion operations, then an array may be more suitable.

Read the idea of ​​solving the problem (using the virtual head node), and recursively implement a set of k flipped linked lists

Guess you like

Origin blog.csdn.net/u012827205/article/details/125664934