Data structure and algorithm series five (bidirectional linked list)

Keywords: network

1. introduction

1.1. Why study data structure and algorithm?

Some people say that data structure and algorithm, computer network, and operating system are the same, away from daily development, except for the interview may not be used in this life!

Some people say that I do business development. As long as I am proficient in API, framework and middleware, can not the code I write fly?

So the question comes: Why study data structure and algorithm?

#Reason 1:
	When interviewing, don't be held back by data structure and algorithm
#Reason 2:
	Do you really want to be CRUD Boy all your life
#Reason 3:
	Engineers who don't want to write open source framework and middleware are not good cooks

1.2. How to systematically learn data structure and algorithm?

I think it's better to learn data structure and algorithm. But I have two puzzles:

1. How to start learning?

2. What is there to learn?

Recommended learning methods:

#Learning methods
1. Starting from the foundation, systematic learning
2. More hands-on, each data structure and algorithm is implemented by code
3. Thinking is more important: understand the implementation idea and don't recite the code
4. Combined with daily development, corresponding application scenarios

Learning content recommendation:

There are many data structures and algorithms. Based on the practical principle, we learn classic and common data structures and algorithms

#Learning content:
1. Definition of data structure
2. Definition of algorithm
3. Complexity analysis
4. Common data structure
	Array, linked list, stack, queue
	Hash table, binary tree, heap
	Skip tables and graphs
5. Common algorithms
	Recursion, sorting, binary search
	Search, hash, greed, divide and conquer
	Dynamic planning, string matching

2. test you.

In the previous [data structure and algorithm Series IV (single linked list)], the definition of linked list is detailed, and the linked list and array are compared. Do you remember what a linked list is? Linked list is to use a group of scattered memory in series through a pointer. Each scattered memory block is called a node. The commonly used chain list in actual development includes: single chain list, two-way chain list and circular chain list.

Let's take a look at the implementation of two-way linked list in this article.

#Test you:
1. Do you know what a two-way list is?
2. Do you know the implementation principle of HashMap (what data structures are used at the bottom)?

Double linked list:

3. cases

3.1. Node encapsulation

Sketch:

Single chain table implementation, each Node only needs to encapsulate data: e, and the subsequent pointer to the next Node: next. In the two-way linked list, you need to add the precursor pointer to the previous Node: prev.

/**
     * Node: node < E >
     */
    class Node<E> {
        protected E e;
        protected Node<E> prev;
        protected Node<E> next;

        public E getE() {
            return e;
        }

        public void setE(E e) {
            this.e = e;
        }

        public Node<E> getPrev() {
            return prev;
        }

        public void setPrev(Node<E> prev) {
            this.prev = prev;
        }

        public Node<E> getNext() {
            return next;
        }

        public void setNext(Node<E> next) {
            this.next = next;
        }
    }

3.2. Complete code

Sketch:

The implementation of linked list tips, add a short node, simplify the complexity of the implementation of linked list code. The implementation of such a linked list with a short head node is called the leading node linked list

package com.anan.struct.linetable;

/**
 * Two way linked list realization idea:
 *      1.A free head node, that is, the head node does not store data
 *      2.This is helpful to simplify the realization of linked list
 */
public class DoubleLinkedList<E> {
    // Linked list size
    private int size;
    public int getSize() {
        return size;
    }

    // Header node
    private Node<E> head;
    // Tail node
    private Node<E> tail;

    public DoubleLinkedList(){
        head = new Node<E>();
        tail = head;

        size ++;
    }

    /**
     * Add element to end of list
     */
    public boolean add(E e){

        // Create node
        Node<E> node = new Node<E>();
        node.setE(e);
        node.setPrev(tail);

        tail.next = node;
        tail = node;

        size ++;
        return true;
    }

    /**
     * Inserts a linked list element at the specified location
     */
    public boolean insertPos(int pos,E e){

        // Get location node
        Node<E> posNode = get(pos);
        if(posNode == null){
            return false;
        }

        // Create a new node
        Node<E> newNode = new Node<E>();
        newNode.setE(e);
        newNode.setPrev(posNode.prev);
        newNode.setNext(posNode);

        posNode.prev.setNext(newNode);
        posNode.setPrev(newNode);

        size ++;
        return true;
    }

    /**
     * Delete end of linked list element
     */
    public boolean remove(){

        tail = tail.prev;
        tail.next = null;

        size --;
        return false;
    }

    /**
     * Delete the linked list element at the specified location
     */
    public boolean delPos(int pos){

        // Get the specified location node
        Node<E> node = get(pos);
        if(node == null){
            return false;
        }

        // delete
        node.prev.setNext(node.next);
        node.next.setPrev(node.prev);

        size --;
        return true;
    }

    /**
     * Get node
     */
    public Node<E> get(int pos){
        // Judge location validity
        if(pos < 1 || pos > size){
            return null;
        }

        Node<E> node = head;
        for(int i = 1; i <= pos; i++){
            node = node.next;
        }

        return node;
    }

    /**
     * Get node data
     */
    public E getValue(int pos){
        // Get node
        Node<E> node = get(pos);
        if(node == null){
            return null;
        }else{
            return node.e;
        }
    }

    /**
     * Node: node < E >
     */
    class Node<E> {
        protected E e;
        protected Node<E> prev;
        protected Node<E> next;

        public E getE() {
            return e;
        }

        public void setE(E e) {
            this.e = e;
        }

        public Node<E> getPrev() {
            return prev;
        }

        public void setPrev(Node<E> prev) {
            this.prev = prev;
        }

        public Node<E> getNext() {
            return next;
        }

        public void setNext(Node<E> next) {
            this.next = next;
        }
    }

}

3.3. Test code

package com.anan.struct.linetable;

/**
 * Test double linked list
 */
public class DoubleLinkedListTest {

    public static void main(String[] args) {
        // Create linked list
        DoubleLinkedList<Integer> list = new DoubleLinkedList<Integer>();

        // Additive elements
        int size = 5;
        for (int i = 0; i < size; i++) {
            list.add(i);
        }

        // 1. Initialize the linked list and print the linked list elements
        System.out.println("1.Initializing linked list and printing linked list elements-----------------------------------------");
        list(list);

        // 2. Insert element at specified location
        System.out.println("2.Insert element at specified location-----------------------------------------");
        list.insertPos(1,666);
        list(list);

        // 3. Delete the end element of the linked list
        System.out.println("3.Delete end of linked list element-----------------------------------------");
        list.remove();
        list(list);

        // Delete the specified location element
        System.out.println("5.Delete the specified location element-----------------------------------------");
        list.delPos(3);
        list(list);

    }

    public static void list(DoubleLinkedList<Integer> list){
        System.out.println("Current list size, size: " + list.getSize());
        for (int i = 1; i < list.getSize(); i++) {
            System.out.println(list.getValue(i));
        }
    }
}

Test results:

1. Initialize the linked list and print the linked list elements-----------------------------------------
Current linked list size, size: 6
0
1
2
3
4
2. Insert element at specified location-----------------------------------------
Current linked list size, size: 7
666
0
1
2
3
4
3. Delete the end element of the linked list-----------------------------------------
Current linked list size, size: 6
666
0
1
2
3
5. Delete the specified location element-----------------------------------------
Current linked list size, size: 5
666
0
2
3

Process finished with exit code 0

4. Discussion and sharing

#Test your answer:
1. Do you know what a two-way list is?
  1.1. On the basis of single linked list, the two-way linked list adds the precursor pointer
  1.2. With the precursor pointer, it is convenient for the chain table to traverse and search from the back to the front
  1.3. Two way linked list, compared with single linked list, refer to the following figure:
  
2. Do you know the implementation principle of HashMap (what data structures are used at the bottom)?
  2.1.HashMap is the mapping table of key and value pairs
  2.2. Its underlying basic data structure is: array
  2.3. Use the array to support subscript random access feature to achieve fast access, time complexity: O(1)
  2.4. Use hash function hash(key) to calculate the original key and the corresponding relationship with array subscript (hash value)
  2.5. Different keys may have the same hash value after hash(key)
  2.6. In case of the same hash value, it is called hash conflict
  2.7. In case of hash conflict, use linked list or red black tree to solve the hash conflict
  2.8. In HashMap, it also applies: array, linked list, red black tree

Posted by kristoff on Wed, 26 Feb 2020 21:35:42 -0800