Review four basic data structures: array, linked list, queue and stack

Time:2021-5-6

file

preface

This article is included in the album:http://dwz.win/HjK, click to unlock more knowledge of data structure and algorithm.

Hello, I’m brother Tong, a hard core man who climbs 26 floors every day and doesn’t forget to read the source code.

Array, linked list, queue and stack are the most basic four structures in data structure. Array and linked list are the foundation of the foundation. All subsequent complex data structures are evolved from them.

In this section, we will review these four structures.

array

On the array, we are more familiar with.

It is a kind of linear data structure, using a group of continuous memory space to store a group of data with the same type.

file

There are three key words in this concept: linear, continuous and the same type.

Linear means that there is no bifurcation, and there is only one element before and after any element at most. Similarly, there are linked lists, queues, etc.

Continuous, its storage in the memory space is continuous, uninterrupted, before and after the two elements close, there is no gap.

With the same type, the elements stored in the array must be of the same type. Of course, in Java, you can use object to represent all types. In essence, they are still of the same type.

It is with the above three features that the array has theRandom accessSo what is random access?

In short, you can quickly locate the elements in the array by subscript, and the time complexity is O (1). How does it do it?

We know that there are only 0 and 1 in the computer, everything can be regarded as various combinations of 0 and 1, and memory is the same.

When we create an array, such asint[] array = new int[]{2, 5, 8, 7};In fact, it returns the location (address) of the array in memory. We know that an int type takes up four bytes, that is, 32-bit 0 or 1. When we access an element with an array subscript of 0, we can directly return the array address, take 32-bit and convert it to int. similarly, when we access an element with an array subscript of 1, we can, Return the array address plus the address of (32 * 1), take 32 bits to convert to int, and so on.

file

This is also the reason why the subscript of array starts from 0 in most languages. Imagine that if the subscript starts from 1, then the calculation of memory address becomes a problemaddress + 32 * (i - 1)This will obviously cause some performance loss.

Linked list

Linked list, which is also a thread data structure, is different from the array, it is not necessarily sequential storage in memory space, in order to ensure the continuity of the elements in the linked list, generally use a pointer to find the next element.

file

The figure above is a typical single linked list structure, in which there is only one pointer to the next element.

If you want to use Java classes to represent element nodes in a single linked list, it will look like this:

class Node {
    int value;
    Node next;
}

Therefore, the linked list does not have the characteristics of random access, in the linked list according to the index to find elements can only start from the beginning (single linked list), its time complexity is O (n).

What we said above is a single linked list. If we add a precursor pointer (pointer to the previous element) to the single linked list, it will become a two-way linked list.

file

The LinkedList in Java is a typical two-way linked list structure. It can be used as a queue or stack, which is very convenient.

If you add the function of HashMap on the basis of the two-way linked list, it will become linked HashMap, cough, pull away.

I hope that students who study the source code analysis of LinkedList and LinkedHashMap can pay attention to my public number owner “tongge read the source code”.

Queue is mentioned here. So, what is queue?

queue

The so-called queue, in fact, is the same as the queue in reality, in which the elements enter from one end and go out from the other end. In English, it is called first in, first out, abbreviated as FIFO.

file

From this figure, we can see that the simplest way to implement queue is to use linked list and reverse the arrow in the figure above.

file

When joining the queue, add the element to the end of the list. When leaving the queue, delete the first element and point the head node to the next node.

Let’s take a look at a simple code implementation of using linked lists to implement queues

public class LinkedQueue {
    Node head;
    Node tail;

    void offer(Integer value) {
        if (value == null) {
            throw new NullPointerException();
        }
        Node node = new Node(value);
        if (head == null) {
            head = tail = node;
        } else {
            tail.next = node;
            tail = node;
        }
    }

    Integer poll() {
        Node first = head;
        if (first != null) {
            head = first.next;
            first.next = null;
            return first.value;
        } else {
            return null;
        }
    }

    static class Node {
        int value;
        Node next;

        public Node(int value) {
            this.value = value;
        }
    }
}

Is it very simple?

Can arrays implement queues?

The answer is yes. There are many ways to use arrays to implement queues. One is to use two pointers: the in pointer and the out pointer, which point to the next in queue and the next out queue respectively.

When joining the team, put the element at the entry pointer and move the entry pointer backward.

When leaving the queue, take out the element at the pointer to return, and move the pointer back at the same time.

When the pointer reaches the end of the array, it returns the beginning of the array.

This forms an array that can be recycled, commonly known as a circular array.

file

At this point, we consider a problem: when the queue is empty or full, the two pointers point to the same location, which seems not easy to handle.

In fact, it’s very simple to introduce a size variable to identify how many elements there are in the queue.

So, how can this be done? Show me the code!

public class ArrayQueue {
    int[] array;
    int offerIndex;
    int pollIndex;
    int size;

    public ArrayQueue(int capacity) {
        this.array = new int[capacity];
        this.offerIndex = this.pollIndex = 0;
        this.size = 0;
    }

    boolean offer(Integer value) {
        if (value == null) {
            throw new NullPointerException();
        }

        if (size == array.length) {
            return false;
        }

        array[offerIndex] = value;
        offerIndex = (offerIndex + 1) % array.length;

        size++;

        return true;
    }

    Integer poll() {
        if (size == 0) {
            return null;
        }

        int value = array[pollIndex];
        pollIndex = (pollIndex + 1) % array.length;

        size--;

        return value;
    }
}

OK, the above is the queue implemented with array. You can see that compared with the queue implemented with linked list, it needs to specify the capacity, which is calledBounded queue, if you need to use array to realize unbounded queue, you need to join the expansion mechanism. Interested students can realize it by themselves.

Next, let’s look at another basic data structure stack.

Stack

Stack is a data structure completely opposite to queue. Its elements are advanced and come out later, just like we put things into a cup. The first thing put in is placed at the bottom. Only when the top thing is taken out can we take out the things pressed below. This kind of behavior is called first in, last out, or Filo for short.

file

Stack has many uses. A lot of processing in the computer is carried out through the data structure of stack, such as arithmetic operation. Prepare two stacks, one for storing numbers and the other for storing symbols. Press characters into the two stacks in turn from the beginning. When the symbol priority is lower than the top element of the stack, take out the top symbol, After all the characters are put into the stack, two elements are taken out from the digital stack in turn, and one element is taken out from the symbol stack for calculation. The result is pushed back to the digital stack and continues to run until the symbol stack is empty, Or until there is only one element left in the number stack, the pop-up number is the final result.

with3 + 2 * 4 -1For example:

file

Well, let’s briefly introduce the stack. Later, we will encounter a large number of data structures.

Postscript

In this section, we review the four most basic data structures: array, linked list, queue and stack.

Speaking of arrays, we can see that memory itself is a large array, and the elements in it are 0 and 1. Can we directly operate these 0 and 1?

The answer is yes.

In the next section, we will introduce bit operation and bitmap data structure. At that time, we will introduce how to use it in detailBitmap to achieve 12306 ticket logic, follow me and get the latest tweets in time.

Pay attention to the owner of the public account “tongge read the source code” to unlock more knowledge of source code, foundation and architecture.

Recommended Today

Looking for frustration 1.0

I believe you have a basic understanding of trust in yesterday’s article. Today we will give a complete introduction to trust. Why choose rust It’s a language that gives everyone the ability to build reliable and efficient software. You can’t write unsafe code here (unsafe block is not in the scope of discussion). Most of […]