以下代码都挺偷懒的,很多需要判断的先决条件我都没写
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;
}
};