Top level understanding of LinkedList

Table of contents

1. Introduction to LinkedList

Structure of LinkedList

2. Analog implementation of LinkedList

2.1 Create a double linked list 

2.2 plug-in method

2.3 Tail insertion method

2.4 Insert at any position

2.5 Find keywords

2.6 Linked list length

2.7 Traversing the linked list

2.8 Delete the node whose keyword is key for the first time

2.9 Delete all nodes whose value is key

2.10 Empty linked list

2.11 Complete code

3. Use of LinkedList 

3.1 Construction of LinkedList

3.2 Introduction to other common methods of LinkedList 

 3.3 Traversal of LinkedList

3.4 The difference between ArrayList and LinkedList


1. Introduction to LinkedList

The bottom layer of LinkedList is a doubly linked list structure, elements are stored in separate nodes, and the nodes are connected by reference.

If you are not clear about doubly linked list or linked list, you can read the article about linked list written by this blogger first.

Top-level understanding of linked list_WHabcwu's Blog-CSDN Blog

In the collection framework, LinkedList also implements the List interface, as follows:

Notice: 

1. LinkedList implements the List interface
2. The bottom layer of LinkedList uses a doubly linked list
3. LinkedList does not implement the RandomAccess interface, so LinkedList does not support random access
4. The efficiency of inserting and deleting elements at any position of LinkedList is relatively high, and the time complexity is O(1)
5. LinkedList is more suitable for the scene of inserting at any position

 

Structure of LinkedList

 

  • Predecessor node: used to store the position of the previous node, represented by prev
  • Successor node: used to store the position of the next node, represented by next
  • The data to be stored, represented by val
  • Head node: represented by head
  • Tail node: represented by last

2. Analog implementation of LinkedList

It is nothing more than adding, deleting, checking and modifying, inserting and deleting at a certain position , and managing and operating data content.

The specific implementation content:

(1) Create a double linked list

(2) Head insertion method

(3) Tail insertion method

(4) Insert at any position

(5) Find keywords

(6) Length of linked list

(7) Traverse the linked list

(8) Delete the node whose keyword is key for the first time

(9) Delete all nodes whose value is key

(10) Clear the linked list

2.1 Create a double linked list 

public class MyLinkedList {
    static class ListNode {
        public int val;
        public ListNode prev;//前驱
        public ListNode next;//后继

        public ListNode(int val) {
            this.val = val;
        }
    }

    public ListNode head;//头节点
    public ListNode last;//尾节点
}

2.2 plug-in method

(1) First determine whether the head node is null, if it is null, then the node is the head node and the tail node.

(2) The head node is not null, point the predecessor node of the original head to the position of the newly added node, and the post-drive node of the newly added node points to the position of the head node.

(3) head points to the location of the newly added node.

    //插法 O(1)
    public void addFirst(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            head = node;
            last = node;
        }else {
            node.next = head;
            head.prev = node;
            head = node;
        }
    }

2.3 Tail insertion method

Similar to the head insertion method

    //尾插法 O(1)
    public void addLast(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            head = node;
            last = node;
        }else {
            last.next = node;
            node.prev = last;
            last = node;
        }
    }

2.4 Insert at any position

The position to be inserted must be legal, if not, we will throw an exception to remind you

public class ListIndexOutOfException extends RuntimeException{
    public ListIndexOutOfException() {
    }

    public ListIndexOutOfException(String message) {
        super(message);
    }
}

Insert at any position, we can divide it into two situations, insert at the beginning, insert at the end, insert in the middle

    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfException("违规数据");
        }
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }

        ListNode cur = findIndex(index);
        //
        ListNode node = new ListNode(data);
        cur.prev.next = node;
        node.next = cur;
        node.prev = cur.prev;
        cur.prev = node;

    }

2.5 Find keywords

Just search directly

    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur = head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

2.6 Linked list length

Use a len variable to record and traverse the linked list

    public int size(){
        int len = 0;
        ListNode cur = head;
        while (cur != null) {
            len++;
            cur = cur.next;
        }
        return len;
    }

2.7 Traversing the linked list

    public void display(){
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

2.8 Delete the node whose keyword is key for the first time

(1) There is no node
(2) The deleted data is at the first
(3) There is no data you want to delete
(4) There is data you want to delete and it is not the first

(5) Delete the last data

 return if found;

    //删除第一次出现关键字为key的节点
    public void remove(int key){
        ListNode cur = head;
        while (cur != null) {
            //开始删除了
            if(cur.val == key) {
                //1. 删除的是头节点
                if(cur == head) {
                    head = head.next;
                    //只有一个节点
                    if(head != null) {
                        head.prev = null;
                    }
                }else {
                    //中间  尾巴
                    cur.prev.next = cur.next;
                    //不是尾巴节点
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        //是尾巴节点
                        last = last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

2.9 Delete all nodes whose value is key

It is almost the same as deleting the node whose keyword appears as key for the first time;

We just need to complete the traversal, and just return to delete.

    //删除所有值为key的节点
    public void removeAllKey(int key){
        ListNode cur = head;
        while (cur != null) {
            //开始删除了
            if(cur.val == key) {
                //1. 删除的是头节点
                if(cur == head) {
                    head = head.next;
                    //只有一个节点
                    if(head != null) {
                        head.prev = null;
                    }
                }else {
                    //中间  尾巴
                    cur.prev.next = cur.next;
                    //不是尾巴节点
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        //是尾巴节点
                        last = last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }

2.10 Empty linked list

You only need to traverse the entire linked list, and set the predecessor and successor nodes of each node to null.

    public void clear(){
        ListNode cur = head;
        while(cur != null) {
            cur.prev  = null;
            cur = cur.next;
            cur.prev.next = null;
        }
        head = null;
        last = null;
    }

2.11 Complete code

public class MyLinkedList {
    static class ListNode {
        public int val;
        public ListNode prev;//前驱
        public ListNode next;//后继

        public ListNode(int val) {
            this.val = val;
        }
    }

    public ListNode head;//头节点
    public ListNode last;//尾节点

    //头插法 O(1)
    public void addFirst(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            head = node;
            last = node;
        }else {
            node.next = head;
            head.prev = node;
            head = node;
        }
    }
    //尾插法 O(1)
    public void addLast(int data){
        ListNode node = new ListNode(data);
        if(head == null) {
            head = node;
            last = node;
        }else {
            last.next = node;
            node.prev = last;
            last = node;
        }
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfException("违规数据");
        }
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }

        ListNode cur = findIndex(index);
        //
        ListNode node = new ListNode(data);
        cur.prev.next = node;
        node.next = cur;
        node.prev = cur.prev;
        cur.prev = node;

    }
    private ListNode findIndex(int index) {
        ListNode cur = head;
        while (index != 0) {
            cur = cur.next;
            index--;
        }
        return cur;
    }
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur = head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
    //删除第一次出现关键字为key的节点
    public void remove(int key){
        ListNode cur = head;
        while (cur != null) {
            //开始删除了
            if(cur.val == key) {
                //1. 删除的是头节点
                if(cur == head) {
                    head = head.next;
                    //只有一个节点
                    if(head != null) {
                        head.prev = null;
                    }
                }else {
                    //中间  尾巴
                    cur.prev.next = cur.next;
                    //不是尾巴节点
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        //是尾巴节点
                        last = last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }
    //删除所有值为key的节点
    public void removeAllKey(int key){
        ListNode cur = head;
        while (cur != null) {
            //开始删除了
            if(cur.val == key) {
                //1. 删除的是头节点
                if(cur == head) {
                    head = head.next;
                    //只有一个节点
                    if(head != null) {
                        head.prev = null;
                    }
                }else {
                    //中间  尾巴
                    cur.prev.next = cur.next;
                    //不是尾巴节点
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                    }else {
                        //是尾巴节点
                        last = last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }

    public int size(){
        int len = 0;
        ListNode cur = head;
        while (cur != null) {
            len++;
            cur = cur.next;
        }
        return len;
    }

    public void display(){
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

    public void clear(){
        ListNode cur = head;
        while(cur != null) {
            cur.prev  = null;
            cur = cur.next;
            cur.prev.next = null;
        }
        head = null;
        last = null;
    }
}

3. Use of LinkedList 

3.1 Construction of LinkedList

3.2 Introduction to other common methods of LinkedList 

 

 3.3 Traversal of LinkedList

    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        linkedList.add(4);
        linkedList.add(5);
        // foreach遍历
        for (int e:list) {
            System.out.print(e + " ");
        }
        System.out.println();
        System.out.println("=====================");
        // 使用迭代器遍历---正向遍历
        Iterator<Integer> iterator1 = linkedList.iterator();
        while(iterator1.hasNext()){
            System.out.println(iterator1.next());
        }
        System.out.println("=====================");
        // 使用反向迭代器---反向遍历
        ListIterator<Integer> iterator2 = linkedList.listIterator(linkedList.size());
        while (iterator2.hasPrevious()){
            System.out.println(iterator2.previous());
        }
    }

3.4 The difference between ArrayList and LinkedList

 


The above is my personal sharing, if you have any questions, welcome to discuss! !

I've seen this, why don't you pay attention and give a free like 

 

Guess you like

Origin blog.csdn.net/WHabc2002/article/details/132469213