数据结构与算法:栈和队列

目录

一、栈

二、队列


一、栈

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据也在栈顶。

        对于栈的实现一般采用的是数组或者链表来实现的。但是我们一般采用的是数组来实现,因为栈的特性是后入先出,采用下标访问,比链表找尾效率要高很多。

#include <iostream>
using namespace std;
template <class T>
class Stack
{
protected:
    T *_stack;
    int _top;
    int _capacity;

public:
    // 值得注意的是当top初始化为0时,为了表示为空栈,让数据的个数就是top的值,以示区分
    Stack(int capacity = 0) : _stack(nullptr), _top(0), _capacity(capacity)
    {
        if (_capacity)
        {
            _stack = new T[_capacity];
        }
    }
    ~Stack()
    {
        if(_stack)
        {
            while(_top!=0)
            {
                cout << _stack[--_top] << endl;
            }
            delete[] _stack;
        }
        _stack = nullptr;
    }
    void Push(T data)
    {
        // 进来先判断栈容量,为0就设置初始值,非0就扩2倍
        if (_capacity == _top)
        {
            int new_capacity = _capacity == 0 ? 4 : _capacity * 2;
            T *tmp = new T[new_capacity];
            // 有数据就先挪动数据
            for (int i = 0; i < _capacity; i++)
            {
                tmp[i] = _stack[i];
            }
            // 判断_stack是否为空,非空就释放掉权限
            if (_stack)
            {
                delete[] _stack;
            }
            // 将tmp指向的栈交给_stack
            _capacity = new_capacity;
            _stack = tmp;
        }
        // 数据进栈(由于_top是从0开始的,所以是先使用,再自增)
        _stack[_top++] = data;
    }
    // 数据出栈
    void Pop()
    {
        // 注意 考虑_top自减后的结果,当_top为0时才能说栈已空,栈顶的元素的序号_top-1
        if (_top > 0)
            _top--;
        else
        {
            cout << "Stack is empty!" << endl;
        }
    }
    T Top()
    {
        if(_top>0)
        {
            return _stack[_top - 1];
        }
        cout << "No Data!" << endl;
        return 0;
    }
    size_t size()
    {
        return _top;
    }
    bool empty()
    {
        return _top == 0;
    }
};

二、队列

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

        队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,挪动数据效率比较低,链表更适合对头部进行操作。

#include <iostream>
using namespace std;
// 队列是一个先进先出FIFO的结构
template <class T>
struct Node
{
    Node<T> *next;
    T data;
    Node(T _data = T()) : data(_data), next(nullptr) {}
};
template <class T>
class Queue
{
protected:
    Node<T> *pHead;
    Node<T> *pTail;
    size_t size;

public:
    Queue() : pHead(nullptr), pTail(nullptr),size(0) {}
    ~Queue()
    {
        while(!Empty())
        {
            Pop();
        }
    }
    // 尾插
    void Push(T data)
    {
        if (pHead == nullptr)
        {
            Node<T> *newNode = new Node<T>(data);
            pHead = pTail = newNode;
        }
        else
        {
            Node<T> *newNode = new Node<T>(data);
            if(pHead==pTail)
            {
                pHead->next = newNode;
                pTail = newNode;
            }
            pTail->next = newNode;
            pTail = newNode;
        }
        size++;
    }
    // 头删
    void Pop()
    {
        if (pHead == pTail)
        {
            if (!pHead)
            {
                cout << "Queue is empty" << endl;
                return;
            }
            else
            {
                delete pHead;
                pHead = pTail = nullptr;
                size--;
            }
        }
        else
        {
            Node<T> *newHead = pHead->next;
            delete pHead;
            pHead = newHead;
            size--;
        }
        
    }
    T Front()
    {
        if (pHead == nullptr)
        {
            cout << "Queue is empty" << endl;
            return NULL;
        }
        else
        {
            return pHead->data;
        }
    }
    T Back()
    {
        if (pHead == nullptr)
        {
            cout << "Queue is empty" << endl;
            return NULL;
        }
        else
        {
            return pTail->data;
        }
    }
    size_t Size()
    {
        return size;
    }
    bool Empty()
    {
        return size == 0;
    }
};

        之后,会将循环队列单独列出来。 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值