栈和队列

1.栈

栈,又名堆栈,是一种运算受限的线性表,因为其仅允许在表的一端进行插入和删除。这一端被称为栈顶,相应的另一端被称为栈底。
按照先进后出的原则存储数据,最先进入的数据被压入栈底,最后进入的数据在栈顶。读取数据的时候从栈顶开始弹出数据。栈具有记忆作用,对栈插入与删除不需要改变栈底指针。

示意图:
这里写图片描述

栈的基本运算:
构造空栈:Init(S)、

判空: Empty(S)、

判满: Full(S)、

进栈: Push(S,x)、可理解为压入,这时栈中会多一个元素。

退栈: Pop(S) 、 可理解为弹出,弹出后栈中就无此元素。

取栈顶元素:StackTop(S),不同与弹出,只是使用栈顶元素的值,该元素仍在栈顶不会改变。
因为栈后进先出的操作方式,所以顺序表实现起来较为简单。

栈的模拟实现:

#pragma once
#include <string>
#include <iostream>
using namespace std;
//栈
//后进先出
template<class T>
class Stack
{
public:
    Stack()    //构造函数
        :_a(NULL)
        , _size(0)
        , _capacity(0)
    {}

    //拷贝构造
    //赋值运算符重载
    //内置类型与string

    ~Stack() {     //析构函数
        if (_a) {
            delete []_a;
            _a = NULL;
        }
    }
public:
    void Push(T a) {    //压栈
        CheckCapatcity();
        _a[_size] = a;
        _size++;
    }
    void Pop() {       //出栈
        if (Top != NULL) {
            _size--;
        }
    }
    size_t Size() {    //返回大小
        return _size;
    }
    bool Empty() {     //判空
        return Top == NULL;
    }
    T& Top() {        //返回栈顶元素
        return _a[_size - 1];
    }
    void Display() {   //打印
            size_t i = 0;
            for (i = 0; i < _size; i++) {
                cout << _a[i] << endl;
            }
    }
protected:
    void CheckCapatcity() {     //获取空间  
        if (_size == _capacity) {
            size_t newCpaticy = _capacity == 0 ? 3 : _capacity * 2;
            T* p1 = new T[newCpaticy]; 
                //内置类型与string
            size_t i = 0;
            for (i = 0; i < _size; i++) {
                p1[i] = _a[i];
            }
            delete _a;
            _a = p1;
            _capacity = newCpaticy;
        }
    }
protected:
    T* _a;     
    size_t _size;    //大小
    size_t _capacity;   //容量
};

2.队列

队列(Queue)也是一种运算受限的线性表,它的运算限制与栈不同,是两头都有限制,插入只能在表的一端进行(只进不出),而删除只能在表的另一端进行(只出不进),允许删除的一端称为队尾(rear),允许插入的一端称为队头 (Front)
因为尾插头删的特性,用链表实现起来更为简单一些,并用一个front指针和一个rear指针来维护数据:
这里写图片描述
实现操作:
判队空:Empty(Q)

判队满: Full(Q)

入队 :Push(Q,x)

出队 : Pop(Q)

#pragma once
#include <iostream>
#include <string>
#include <assert.h>
using namespace std;

//队列
//单链表实现
//先进先出
template<typename T>
class LinkQueue
{
public:
    LinkQueue()
        :_a(NULL)
        ,next(NULL)
    {}
    LinkQueue(const T& t)
        :_a(t)
        ,next(NULL)
    {}
    ~LinkQueue()
    {}
public:
    T _a;
    LinkQueue *next;
};

template<typename T>
class Queue
{
public:
    Queue()
        :_front(NULL)
        , _rear(NULL)
    {}
    void Push(T t) {    //尾部插入
        if (_front == NULL)   //
        {
            _front = new LinkQueue<T>(t);
            _rear = _front;
        }
        else {
            _rear->next = new LinkQueue<T>(t);
            _rear = _rear->next;
        }
    }
    void Pop(){   //头部删除
        assert(this->_front&&this->_rear);
        if (_front == _rear) {
            return;
        }
        LinkQueue<T> *cur = _front->next;
        _front->next = cur->next;
        delete cur;
        cur = NULL;
    }
    size_t Size() {
        assert(this);
        size_t count = 1;
        LinkQueue<T> *cur ;
        cur = _front->next;
        while (cur != NULL) {
            cur = cur->next;
            count++;
        }
        return count;
    }
    bool Empty(){
        return _front == _rear;
    }
    ~Queue(){
        LinkQueue<T> *next = _front->next;
        while (next != NULL) {
            delete _front;
            _front = next;
            next = next->next;
        }
    }
    T& Top() {
        if (!Empty()) {
            LinkQueue<T> * Node = _front->next;
            return *(Node->_a);
        }
        return NULL;
    }
public:
    LinkQueue<T> *_front;
    LinkQueue<T> *_rear;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值