stack&queue&priority_queue

Table of contents

1. Container Adapter

2. Deque

1. Deque related functions

2. About deque

3. The underlying implementation of deque

4. Design flaws of deque

5 Conclusion

3. stack

1. Stack related functions

2. Use of stack related functions

3. Stack simulation implementation

4.queue

1. Queue related functions

2. Use of queue related functions

3. Simulation implementation of queue

五、priority_queue

1. Related functions of priority_queue

2. Use of priority_queue


1. Container Adapter

First of all, an adapter is a design pattern that converts the interface of a class into another interface that the customer wants.

stack and queue are not divided into containers, but are called container adapters, because stack, queue, and priority_queue just wrap the interfaces of other containers. stack, queue, and priority_queue use deque by default, as shown in the following figure:


2. Deque

There is a new container that needs to be introduced here, because the second parameters of stack and queue mentioned next, that is, the default parameters are all given to deque.

So you need to know about this new container

1. Deque related functions

2. About deque

First, using deque requires the header file deque.    

Observing the function of deque, we can see that:

Compared with vector, deque supports header deletion, and compared with list, it supports random access , which is equivalent to the combination of vector and list.

Therefore, deque supports both insertion and deletion at any position and random access.

But deque is actually not as omnipotent as imagined. You can think about it. If it is really so good, then just learn deque directly. Why do you still need to learn vector and list? Please see the analysis below for the specific reasons:


3. The underlying implementation of deque

deque is a double-ended queue

Specifically it looks like this:

deque has small array buffers . Each small array stores a part of the data. If the space for tail insertion is full, open another small array buffer at the back. If you want to insert at the beginning, open another small array buffer at the front.

There is a centrally controlled pointer array. Each position stores a pointer, pointing to a small array buffer.

And there is a detail. When applying for the first buffer, that is, the small array in the middle of the picture above, it is not applied from the first position of the array. It is applied from the middle of the central control pointer array . When expanding as shown in the picture , then the position of the pointer of the subsequent buffer is behind the position of the pointer of the first buffer in the array, and the position of the pointer of the previous buffer is in front of the pointer of the first buffer in the array.

Assuming that the buffer of each small array is full of 8 spaces, then the situation after head-to-tail expansion should be as follows:

What needs special attention is that when the header is expanded, data is inserted into the buffer from right to left.

Now that we understand how deque supports insertion and deletion at any position, let’s look at how deque supports random access:

For example, how to access the nth data?

It's very simple, there are two formulas:

(i - the number of elements in the first buffer) / 8: This formula calculates which buffer the element is in

(i - the number of elements in the first buffer) % 8: This formula calculates the position of the element in that buffer

This is how deque supports [], that is, how it supports random access

4. Design flaws of deque

①The calculation of operator[] is relatively complex. If used in large quantities, the performance will decrease.

②Insertion and deletion in the middle are not efficient

5 Conclusion

①Compared with vector and list, deque is very suitable for head and tail insertion and deletion, so deque is very suitable as the default adaptation container for stack and queue.

②Multi-purpose list for insertion and deletion in the middle

③ Random access to multi-purpose vector


3. stack

The stack meets the characteristics of last-in-first-out, that is, last-in first-out, LIFO

1. Stack related functions

2. Use of stack related functions

Insert 1, 2, 3, 4 in order, use push, empty, top, pop functions to operate, observe the pictures and print the results to understand the usage

The use of stack and queue is basically these. The rest can be learned in conjunction with the previous container use. The following simulation implementation details the relevant knowledge.

3. Stack simulation implementation

First we simulate the implementation of stack in our own namespace

It can be observed that there are two template parameters of stack, one is data type T, and the other is Container, which is a container

You can also see that the member of the stack class simulated is Container _con, that is, as long as the container that meets the relevant functions of push, pop, top, empty, size, etc. can be used, the template parameters can be passed in.

The following is the code to simulate the stack:

Let’s look at the specific use of container adapters:

You can see that we use the fcy namespace when using stack , so the test content is simulated and implemented by ourselves.

It can be observed that when stack is usually used, stack<int> is used like this. After using the container adapter, you can choose the underlying container you want. Here we pass in vector, because vector can meet the basic functions of stack, so pass Enter the vector to adapt the stack here.

Of course, not only vector is satisfied, but list is also satisfied, so the output result of passing in list here is the same:

Both vector and list can meet the basic functions of stack, so we can pass them in. We don’t care what container is passed in, as long as it can adapt to the stack.

And we all know that the underlying layers of vector and list are different, but they can both be passed in to adapt to the stack we want. This is what we call an adapter.

The deque we talked about above is the default container, that is, we need to give the stack a default container, so that when we do not pass the specified container, deque adaptation will be used by default, that is, a default value will be given in the template parameter section.

In this way, we don’t need to manually transfer the container when we use it, that is:



4.queue

The queue meets the characteristics of first-in first-out, that is, first-in first-out, FIFO

1. Queue related functions

2. Use of queue related functions

Insert 1, 2, 3, 4 in order, use the push, empty, front, and pop functions to operate, observe the pictures and print the results to understand the usage


3. Simulation implementation of queue

We simulate the implementation of stack in our own namespace

Like stack, there are two template parameters, one is the data type T, and the other is Container, which is a container. Deque is used by default.

As long as the container meets the relevant push, pop, back, front, empty, size and other functions, it can be passed in as template parameters when using it.

The following is the code to simulate the queue:

The following is a specific test of the queue function simulated in the fcy namespace. The container does not need to be passed by default:

Of course, we can also pass in the list container to adapt the queue, that is:

Vector adaptation cannot be used here because vector does not support the deletion of the head , and the queue is inserted at the tail and deleted at the head.


五、priority_queue

priority_queue is called a priority queue, and the bottom layer is a heap

priority_queue is also a container adapter

priority_queue has three template parameters:

The first is the data type

The second one is a container, which is adapted by vector by default because there are more random accesses.

The third is a functor, a function about sorting, which defaults to a large heap. You can simulate it by yourself and implement an incoming

1. Related functions of priority_queue

2. Use of priority_queue

The priority_queue constructor can pass in the iterator initialization

As shown below, initialize with array, default is large, and print out in descending order:

If you want to turn it into a small heap and output it in ascending order, you need to change the functor to greater. Greater is included in the header file functional.

And if you want to pass in the third parameter functor yourself, the second parameter must also be passed in manually, that is:


The use of priority_queue is also very simple. The following figure shows the use of the four most commonly used functions, push, pop, empty, top

It can be understood from the output results that the priority queue is a large heap by default , because each time the data on the top of the heap is taken, and then popped, the largest one is taken out.

If you want to turn it into a small heap and output it in ascending order, you need to change the functor to greater. Greater is included in the header file functional.

And if you want to pass in the third parameter functor yourself, the second parameter must also be passed in manually, that is:

Guess you like

Origin blog.csdn.net/m0_64411530/article/details/132745144