[C++/数据结构] 2.1 栈(Stack)和队列(Queue)

以下代码都挺偷懒的,很多需要判断的先决条件我都没写

1 栈和队列的顺序存储

由于栈和队列是顺序表的子集,所以基本没什么可将的,代码的话基本可以照搬我之前瞎写的一些数据结构文章。

#include <iostream>
using namespace std;

template <class T>
class Stack_sq
{
private:
    T *arr;

    int rear;

public:
    Stack_sq(int _len)
    {
        rear = 0;
        arr = new T[_len];
    }
    void DestroyStack()
    {
        delete[] arr;
        arr = nullptr;
    }
    ~Stack_sq()
    {
        if (arr)
        {
            delete[] arr;
            arr = nullptr;
        }
    }

    void push_back()
    {
    }

	//实现连续压栈,不了解相关语法的,请搜索variadic template,实际上这用initlist会好很多
    template <class T1, class... Types>
    void push_back(const T1 &firstElem, const Types &...elems)
    {
        arr[rear] = firstElem;
        rear++;
        push_back(elems...);
    }

    T pop_back()
    {
        rear--;
        return arr[rear];
    }

    bool empty()
    {
        return rear == 0 ? 1 : 0;
    }

    int size()
    {
        return rear;
    }

    void print()
    {
        for (int i = 0; i < rear; i++)
        {
            cout << arr[i] << " ";
        }
        cout << endl;
    }
};

template <class T>
class queue_sq
{
private:
    T *arr;
    int rear;
    int top;

public:
    queue_sq(int len)
    {
        arr = new T[len];
        rear = 0;
        top = 0;
    }
    ~queue_sq()
    {
        if (arr)
        {
            delete[] arr;
        }
    }

    T pop_front()
    {
        if (top < rear)
        {
            return arr[top++];
        }
    }

    void push_back() {}
    template <class T1, class... Types>
    void push_back(const T1 &elem, const Types &...elems)
    {
        arr[rear++] = elem;
        push_back(elems...);
    }

    void print()
    {
        for (int i = top; i < rear; i++)
        {
            cout << arr[i] << " ";
        }
        cout << endl;
    }
    int size()
    {
        return rear - top;
    }
    bool empty()
    {
        return rear == top ? 1 : 0;
    }
};
int main()
{
    // Stack_sq<int> arr{5};
    // arr.push_back(1);
    // arr.push_back(2);
    // arr.push_back(3);
    // cout << arr.size() << endl;
    // arr.pop_back();
    // cout << arr.size() << endl;
    //arr.push_back(2,3,4,1);
    // arr.print();

    queue_sq<int> arr1{5};
    arr1.push_back(1);
    arr1.push_back(2);
    arr1.push_back(3);
    cout << arr1.size() << endl;
    arr1.print();

    arr1.pop_front();
    cout << arr1.size() << endl;
    arr1.print();
    arr1.push_back(5, 2, 7, 1);
    arr1.print();

    system("pause");
    return 0;
}

2 栈和队列的链式存储

由于目前对STL的源码剖析还不够深入,我还没办法了解list是如何实现初始化的连续赋值(目前该问题已解决,您可以参考线性表的链式存储这篇文章的 5 基于C++11新特性的改进 来实现这种操作),然后自动连接节点的,所以这部分的代码在运用起来时贼难用,建议直接使用STL中的list代替。

为避免写流水账,且因为这部分内容其实是线性表的链式存储的子集,所以我没写完整个代码,需要复制以下代码到上面文章的的class LinkList里面才能运行。

    void push_back(LNode* n)
    {
        auto p = next;
        while(p!=NULL)
        {
            p = p->next;
        }
        p->next = n;
    }
    
    void pop_front()
    {
        auto p = next->next;
        next = p;        
    }

3 STL下的栈和队列

注意!实际上STL有直接对应的stack和queue

#include <iostream>
#include <list>
#include <vector>
using namespace std;

template <class T1>
void print(T1 con)
{
    for (auto i : con)
    {
        cout << i << " ";
    }
    cout << endl;
}

int main()
{
    vector<int> v1{1, 2, 3, 4};
    v1.push_back(2);
    print(v1);
    v1.pop_back();
    print(v1);

    list<int> l{1, 2, 3, 4};
    l.push_back(2);
    print(l);
    l.pop_front();
    print(l);
    system("pause");
    return 0;
}

当然你也可以直接使用stack
template <class T, class Container = deque<T> > class stack;
和queue
template <class T, class Container = deque<T> > class queue;
他们可以被认为是vector,list的子集,功能少一些。

4 用栈来造一个队列;用队列造一个栈

这波啊,这波是双向奔赴了属于是。

先考虑用栈做一个队列

class MyQueue
{
private:
    int len;
    stack<int> s1;
    stack<int> s2;

public:
    MyQueue(initializer_list<int> initList)
    {
        for (auto i : initList)
        {
            s1.push(i);
        }

        while (!s1.empty())
        {
            s2.push(s1.top());
            s1.pop();
        }
    }

	//注意输入的形式是s.push({1,2,3,4});
    void push(initializer_list<int> initList)
    {
        while (!s2.empty())
        {
            s1.push(s2.top());
            s2.pop();
        }
        for (auto i : initList)
        {
            s1.push(i);
        }
        while (!s1.empty())
        {
            s2.push(s1.top());
            s1.pop();
        }
    }

    void pop()
    {
        s2.pop();
    }

    void top()
    {
        s1 = s2;
        int tmp;
        while (!s1.empty())
        {
            tmp = s1.top();
            s1.pop();
        }
        cout << tmp;
    }
    
    void toPrint()
    {
        s1 = s2;
        while (!s1.empty())
        {
            cout << s1.top() << ' ';
            s1.pop();
        }
    }
};

用队列来实现栈的功能,这部分的关键在于将队列看成一个“环”,通过一定的循环把我们想要处理的值放到pop,front这两个队列操作所在的位置。

class MyStack
{
private:
    queue<int> q1;

public:
    MyStack(initializer_list<int> initList)
    {
        for (auto i : initList)
        {
            q1.push(i);
        }
    }

    void push(int x)
    {
        q1.push(x);
    }

    void top()
    {
        int i = 0;
        int len = q1.size();
        while (i < len - 1)
        {
            q1.push(q1.front());
            q1.pop();
            i++;
        }
        auto tmp = q1.front();
        cout << tmp << endl;
        //还原回来
        q1.push(q1.front());
        q1.pop();
    }

    void pop()
    {
        int i = 0;
        int len = q1.size();
        while (i < len - 1)
        {
            q1.push(q1.front());
            q1.pop();
            i++;
        }
        q1.pop();
    }

    void toPrint()
    {
        //替身,否则q1将会被销毁
        auto tmp = q1;
        while (!tmp.empty())
        {
            cout << tmp.front() << ' ';
            tmp.pop();
        }
        cout << endl;
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值