数据结构与算法学习笔记——栈ADT C++实现


1 特点

栈的数据结构为线性结构

栈只能在同一位置进行插入和删除,这个位置叫做栈顶。后进先出(LIFO),生活中的例子有坐电梯、去西红门绞肉机坐地铁

2 包含的操作

  • 入栈(压栈)
  • 出栈(弹出)
  • 读栈顶元素

3 实现方式

3.1 基于数组实现(应用较多)

基于数组实现(非vector)的空间是静态的,空间不能再扩展,因此会出现空间不够的情况;但是从ADT角度出发不会有空间不够的情况,空间不够属于实现时的限制

编程时要考虑指针移动操作与数据操作时的顺序,以及空间是否为满/空

Stack.h

#include <iostream>
const int MAX = 10;   // 数组大小

template <typename T>
class Stack
{
public:
    Stack();
    ~Stack();
    void push(T);
    T pop();
    T top();
private:
    int _pointer;
    T _array[MAX] = {0};    // 数据放在数组中
protected:
};

Stack.cpp

#include "Stack.h"

/*
 * 令pointer=-1,表示空栈
 */
template <typename T>
Stack<T>::Stack()
{
    _pointer = -1;
}
/*
 * 析构函数
 */
template <typename T>
Stack<T>::~Stack()
{

}
/*
 * 入栈
 * 从ADT角度出发没有空间不够的情况,但这里的具体实现还是把这个情况纳入了考虑
 */
template <typename T>
void Stack<T>::push(T data)
{
    if(_pointer < MAX-1)
        _array[++_pointer] = data;
    else
        std::cout << "the array is full, failed to push" << std::endl;
}
/*
 * 出栈
 * 如果在栈为空的情况下出栈,返回值为-1并报错
 */ 
template <typename T>
T Stack<T>::pop()
{
    T temp;
    if(_pointer > -1)
    {
        temp = _array[_pointer];
        _array[_pointer] = 0;    // 这里用元素==0表示删除
        _pointer--;
    }
    else
    {
        temp = -1;
        std::cout << "the stack is empty, failed to pop" << std::endl;
    }
    return temp;
}
/*
 * 读栈顶元素
 */
template <typename T>
T Stack<T>::top()
{
    if(_pointer > -1)
    {
        return _array[_pointer];
    }
    else
    {
        std::cout << "the stack is empty" << std::endl;
        return T(-1);
    }    
    
}

template class Stack<int>;
template class Stack<float>;
template class Stack<double>;

main.cpp

#include <iostream>
#include "Stack.h"

int main()
{
    Stack<int> stack1;
    for(int i = 0; i < MAX + 1; i++)
    {
        int data;
        std::cout << "input the number you want to push:" << std::endl;
        std::cin >> data;
        stack1.push(data);
    }
    std::cout << "top a number, the number is: " << stack1.top() << std::endl;
    for(int i = 0; i < MAX + 1; i++)
    {
        std::cout << "pop a number, the number is: " << stack1.pop() << std::endl;
    }              
    return 0;
}

运行结果:
在这里插入图片描述

3.2 基于单链表实现

链表需要有表头,编程时注意给表头赋值

Stack.h

#include <iostream>

template <typename T>
struct list
{
    T data;
    list *next;
};

template <typename T>
class Stack
{
public:
    Stack();
    ~Stack();
    void push(T);
    T pop();
    T top();
private:
    list<T> *_pointer;
    list<T> *_head;
protected:
};

Stack.cpp

#include "Stack.h"

/*
 * pointer==NULL时说明为空栈
 */
template <typename T>
Stack<T>::Stack()
{
    _head = _pointer = NULL;
}
/*
 * 析构函数
 */
template <typename T>
Stack<T>::~Stack()
{
    list<T> *p1, *p2;
    p1 = p2 = _head;
    for(;p1 != NULL;)
    {            
        p1 = p1->next;
        delete p2; 
        p2 = p1;           
    }
}
/*
 * 入栈
 */
template <typename T>
void Stack<T>::push(T data)
{
    list<T> *p = _pointer;
    _pointer = new list<T>;
    _pointer->data = data;
    _pointer->next = NULL;
    if(p == NULL)
    {
        _head = _pointer;
    }
    else
    {
        p->next = _pointer;
    }
}
/*
 * 出栈
 * 如果在栈为空的情况下出栈,返回值为-1并报错
 */ 
template <typename T>
T Stack<T>::pop()
{
    T temp;
    if(_pointer == NULL)
    {
        _head = NULL;
        std::cout << "the stack is empty, failed to pop" << std::endl;
        temp = -1;
    }
    else if(_pointer == _head)
    {
        temp = _pointer->data;
        delete _pointer;
        _pointer = _head = NULL;
    }
    else
    {
        temp = _pointer->data;
        list<T> *p;
        for(p = _head; p->next != _pointer; p = p->next)
            ;         
        delete _pointer;
        _pointer = p;
        _pointer->next = NULL;
    }
    return temp;    
}
/*
 * 读栈顶元素
 */
template <typename T>
T Stack<T>::top()
{
    if(_pointer == NULL)
    {
        std::cout << "the stack is empty" << std::endl;
        return T(-1);
    }
    else
    {
        return _pointer->data;
    }
}

template class Stack<int>;
template class Stack<float>;
template class Stack<double>;

main.cpp

#include <iostream>
#include "Stack.h"

int main()
{
    Stack<int> stack1;
    for(int i = 0; i < 5; i++)
    {
        int data;
        std::cout << "input the number you want to push:" << std::endl;
        std::cin >> data;
        stack1.push(data);
    }
    std::cout << "top a number, the number is: " << stack1.top() << std::endl;
    for(int i = 0; i < 6; i++)
    {
        std::cout << "pop a number, the number is: " << stack1.pop() << std::endl;
    }        
    return 0;
}

运行结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值