Stack: first in, last out, use of STL standard stack: #include < stack >
Queue: last in and last out --#include < queue >
Stack basic functions:
push(x); Stack pressing
pop(); Pop stack, do not return any value
top(); Returns the element at the top of the stack
empty(); Return true/false to judge whether the stack is empty
Use queue to realize the basic operation of stack:
Idea:
If the input push elements are in reverse order, the final pop operation only needs to execute the front operation of the queue
Step 1: create a temporary queue. Each element push enters the temporary queue first
Step 2: press the front operation of the original queue element into the temporary queue
Step 3: push the temporary queue elements into the original queue and complete the reverse order input of data eg:1,2,3,4,5 The sequence from front to back in the queue is: 5,4,3,2,1
Use the stack to implement the queue:
Idea:
Idea: create a temporary stack. Each push operation will press all the elements in the temporary stack into the temporary stack. After taking them out, press all the elements in the temporary stack into the original stack
Example 3 - stack containing min function
We found that there is no way to record the minimum value only with one variable, because if the currently stored minimum value is deleted, we don't know what the second smallest value is. We need to know the record value of the lowest minimum value to make it an element that may not be repeated from top to bottom (minimum, minimum.., second small, second small,. Third small, third small...), This depends on how many stack elements are more than the number of current elements, and how many duplicate stack elements are there (look at the figure directly, and it's easy to understand!)
The code is simple
Thinking: in fact, this is an idea of using monotone stack. We record the minimum value, the second smallest value and the third smallest value from top to bottom, but we can't sort from top to bottom like monotone stack. Therefore, we order, but we don't order completely
Example 4 - Legal stack sequence
(that is, whether the current stack out sequence is legal)
Idea: use a queue to store the current sequence. We press the input sequence on the stack in turn. If the top element of the current stack is the same as the header element of the queue, we pop up the stack and pop up the sequence header element. Finally, if the queue element and stack element are empty, it indicates that it is a legal sequence
code
(Note: the second frame should be stacked to determine whether it is empty, because if it is NULL, there will be an error bouncing the stack here)
Example 5 - Implementation of simple calculator
Use stack to complete+-
operation
Why use stack as a data structure? Use the stack to handle the priority of '()'. If the left parenthesis is encountered, it means that the top elements of the stack of the two data stations cannot be taken out. When the + - sign is encountered, count_flag=1
Use finite state automata to process code (state transition completed)
STL maximum binary stack / minimum binary stack
Also called priority queue ()
Example 6 - the K-th largest value in the array
We can sort first, and then directly take down the elements marked K
However, the time complexity of sorting is O(n*logn)
Therefore, we can consider using heap, so that the time complexity is O(logk*n) Where logk is the time complexity required to maintain the heap, and N is the time complexity to traverse the array
We consider maintaining a minimum heap. When the heap elements are not satisfied, we can directly push them in. However, when they are full, we first see whether this element is greater than the maximum value, and if so, push them into the binary heap. Then rearrange the binary heap according to the rules of the minimum heap (the source of the time complexity of logk!)
Example 7 - how to get the median
Idea: use the nature of the heap to dynamically maintain a maximum heap and a minimum heap. The top elements of the maximum heap are smaller than those of the minimum heap. In this way, if there are more elements in the two heaps, the top elements with more elements will be taken as the median. However, if the number of two heap elements is the same, the top elements will be added and divided by two
Additional elements:
Case 1 - if the number of maximum heap elements and minimum heap elements is equal, and the new element is less than the top of the maximum heap or greater than the top of the minimum heap, push directly
Case 2 - the maximum number of heap elements is more than the minimum number of heap elements
a. The new element is smaller than the maximum heap top. First pop the maximum heap top element, then push it into the minimum heap, and finally push the new element into the maximum heap
b. If the new element is larger than the top of the maximum heap, push the new element directly into the minimum heap
Case 3 - the minimum number of heap elements is more than the maximum number of heap elements
a. If the new element is smaller than the minimum heap top, it can be directly added to the maximum heap
b. If the new element is larger than the minimum heap top, we need to push the heap top element of the minimum heap to the maximum heap, remove the heap top element of the minimum heap, and then add the new element to the minimum heap. Balance both sides
We will find a very interesting question: Why are new elements always compared with the head node of the binary tree with more elements?
Because the top node of more trees is the median, we are actually comparing with the median!
The final code is as follows:
#include<queue> #include<cstdio> using namespace std; priority_queue<int, vector<int>, greater<int> > small_que; //g_ Small top pile priority_queue<int, vector<int>, less<int> > big_que; //l_ Large top reactor int addNum(int num) { //There are four cases: the maximum heap is more, the minimum heap is more, the number of nodes is equal, and it is empty if (big_que.empty()) { big_que.push(num); return num; }else if (big_que.size() > small_que.size()){ if (num < big_que.top()) { small_que.push(big_que.top()); big_que.pop(); big_que.push(num); } else if (num > big_que.top()) { small_que.push(num); } }else if (small_que.size() > big_que.size()){ if(num>small_que.top()){ big_que.push(small_que.top()); small_que.pop(); small_que.push(num); } else if (num < small_que.top()) { big_que.push(num); } } else{ //At this time, the number of the two heaps is equal if (num < big_que.top()){ big_que.push(num); }else if (num > small_que.top()){ small_que.push(num); } } return (big_que.size() > small_que.size() ? big_que.top() : (big_que.size() == small_que.size() ? (big_que.top() + small_que.top()) / 2 : small_que.top())); } int main() { int temp; int mid; vector<int> vec; while (scanf_s("%d", &temp)!=EOF) { mid=addNum(temp); printf("The median for this is:%d\n", mid); } return 0; }