Data structure -- basic implementation and explanation of stack (C + + description)

Keywords: C++ Programming

Definition of stack

Stack, also known as stack, is a linear table with limited operation. A linear table that is restricted to insert and delete operations only at the end of the table. This end is called the top of the stack, and the other end is called the bottom of the stack. Inserting new elements into a stack is also called pushing, pushing or pressing. It is to put new elements on top of the stack to make it a new stack top element. Deleting elements from a stack is also called pushing out or pushing back. It is to delete the stack top elements and make the adjacent elements become new stack top elements. ——Baidu Encyclopedia

Simple definition: stack is a linear table that only allows insertion and deletion at the end of the table

How to understand the concept of stack

① take an example in life: I piled up a pile of clothes in a storage box, and one of my jerseys was at the bottom. If I wanted to take this clothes, I had to take out all the clothes on it. But because the box only had one opening, I could only take things from it. I still thought in my heart that I shouldn't put the jerseys in early and guide them. The result is first in, then out!

Can't you give an example from a computer? This is the arrangement!

② many operations in the computer are implemented by the principle of stack. For example, the "forward" and "backward" keys in common browsers can be implemented by the principle of stack. Let's use the diagram to illustrate.

We can use two stacks (temporarily called M, N) to realize forward and backward.

  • We browse page A, page B and page C respectively, so we press these pages into the stack in turn, that is, open the page part in the figure.
  • When the user clicks back, we need to return to page B, but since page C is above B, we must first pop up page C from stack M and put it in stack N, that is, the back part in the figure.
  • But if the user suddenly wants to go back to page C, the principle is similar. Just pop up page C in stack N and press it into stack M again.
  • If the user opens a new interface d when browsing the B interface, then C can't access it by going forward and backward, so stack M needs to empty stack N while pressing in page D.

Stack terminology

Top of stack: a section that allows insertion and deletion becomes the top of the stack

Bottom of stack: the other end of the table is called the bottom of the stack (where the first element enters)

Stack pressing: the operation of inserting elements at the top of the stack is called stack pressing, or stack pushing or stack pushing.

Stack out: the operation to delete the top element of the stack is called stack out, also known as pop stack, or back stack

Empty stack: empty table without elements

Stack overflow: when the stack is full, if there is another element pressing the stack, it will overflow. When the stack is empty, it will overflow when the stack is out.

Abstract data type of stack

#ifndef _STACK_H_
#define _STACK_H_
#include <exception>
using namespace std;


template <class T>
class Stack { 
public: 
    virtual bool empty() const = 0; 
    virtual int size() const = 0; 
    virtual void push(const T &x) = 0; 
    virtual T  pop() = 0;              
    virtual T getTop() const = 0;  
    virtual void clear() =0;
    virtual ~Stack() {}
};

/*
    Custom exception class
*/

// Used to check the validity of the scope
class outOfRange:public exception {
public:    
   const char* what()const throw()    
   {    return "ERROR! OUT OF RANGE.\n";    } 
};  

// Used to check the validity of the length
class badSize:public exception {
public:    
   const char* what()const throw()    
   {    return "ERROR! BAD SIZE.\n";    }  
};

#endif

Sequential stack -- sequential storage structure of stack

As we mentioned at the beginning, stack is actually a special case of linear table, so the implementation of stack is the same as that of linear table. We use a one-dimensional array to store elements, so there must be a head. We need to determine the position of the bottom of stack. Generally, we choose one end of 0 as the bottom of stack, which is more convenient to understand and operate, especially , we set an integer variable top to store the location (subscript) of the stack top element, also known as the stack top pointer

(I) type description of sequence stack

At the beginning, assign - 1 to top, indicating that the stack is empty. After the element is in the stack, top + 1, after the element is out of the stack, top - 1

//  array-based stack: definition and implementation for some methods 
 
#ifndef _SEQSTACK_H_
#define _SEQSTACK_H_

#include "Stack.h" 
 
template <class T>      
class seqStack : public Stack<T> {       
private:
    T * data;
    int top;
    int maxSize;
    void resize();
public:
    seqStack(int initSize = 100) {
        if(initSize<=0) throw badSize();
        data = new T[initSize];
        maxSize = initSize ;    
        top = -1;  
    }       
    ~seqStack(){ delete [] data;}
    bool empty() const{ return top == -1;}      
    int size() const{ return top + 1; } 
    void clear() { top = -1; }                 // Empty stack contents 
    void push(const T &value);   
    T  pop();   
    T  getTop() const;            
}; 

#endif

(two) enter the stack

template <class T>
void seqStack<T>::push(const T &value) {    
    if (top == maxSize - 1) resize();
    data[++top] = value;
}   

(three) stack

template <class T>
T seqStack<T>::pop() {     
    if(empty())throw outOfRange();
    return data[top--];    
}   

(IV) top element

template <class T>
T seqStack<T>::getTop() const{
    if(empty())throw outOfRange();
    return data[top];
}

(five) capacity expansion

template <class T>
void seqStack<T>::resize(){
    T * tmp = data;
    data = new T[2 * maxSize];
    for (int i = 0; i < maxSize; ++i)
        data[i] = tmp[i];
    maxSize *= 2;
    delete[] tmp;
} 

(VI) shared space of two stacks

Stack is a data structure compared with linear table. There is no need to move elements when inserting or deleting, but there is still a big disadvantage. That is, we must allocate the space in advance. Once the space is full, and then there are elements near the stack, we must use programming methods to expand the array, which is still troublesome.

Sometimes we need more than one stack. Our previous approach is to design an array of appropriate size according to the actual problem as much as possible, but it's obviously difficult, and it's often the case that one stack is full, while the other stack may still have a lot of space. If we can make use of those free positions, we will come next. A way of thinking about such a technique.

In fact, we put the bottom of the two stacks on both ends of the array, and then the two stacks are in the opposite position, and gradually close to the middle. As long as the two top pointers do not meet, the two stacks can be used all the time.

Chain stack -- chain storage structure of stack

Chain stack is a stack with chain storage structure, which is similar to our chain storage in single chain table. We will set a pointer top to the top of the stack, and when top == NULL, the stack is empty.

(I) type definition of chain stack

#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
#include <iostream> 

#include "Stack.h" 

template <class T>
class linkStack : public Stack<T> 
{
private:
    struct Node {
        T data;
        Node* next;
        Node(){ next = NULL; }
        Node(const T &value, Node *p = NULL){ data = value; next = p;}
    };
    Node* top;
public:
    linkStack(){ top = NULL; }
    ~linkStack(){ clear(); }
    void clear();
    bool empty()const{ return top == NULL; }
    int size()const;
    void push(const T &value);
    T  pop();
    T getTop()const;
};
#endif

(II) empty the stack

template <class T>
void linkStack<T>::clear() {
    Node *p;
    while (top != NULL) {
        p = top;
        top = top->next;
        delete p;
    }
}

(3) number of elements in the stack

template <class T>
int linkStack<T>::size()const {
    Node *p = top;
    int count = 0;
    while (p){
        count++;
        p = p->next;
    }
    return count;
}

(four) enter the stack

template <class T>
void linkStack<T>::push(const T &value) {
    Node *p = new Node(value, top);
    top = p; 
}

(five) stack

template <class T>
T linkStack<T>::pop() {
    if (empty())throw outOfRange();
    Node *p = top;
    T value = p->data;
    top = top->next;
    delete p;
    return value;
}

(VI) get the top element of the stack

template <class T>
    T linkStack<T>::getTop() const { 
    if(empty())throw outOfRange();
    return top->data;
}

Ending:

If there are any shortcomings or mistakes in the article, please leave a message and share your ideas. Thank you for your support!

If you can help, then pay attention to me! If you prefer to read wechat articles, please pay attention to my public account

We don't know each other here, but we are working hard for our dreams.

A public number that insists on pushing original development technology articles: ideal more than 20 years

Posted by tfburges on Tue, 22 Oct 2019 13:35:11 -0700