理论基础
栈与队列的底层实现有多种,可插拔,不归属于容器,而应该叫容器适配器。
232.用栈实现队列
分两个栈分别入、出,入直接进栈就可以,出栈需要分两种情况,如果出栈里有元素,弹一个出来就可以,如果是空的,要把所有入栈的元素都放到出栈里,保证顺序不变。
C++
注意pop是void类型不返回值,要先通过top获取值,再把元素弹出。
class MyQueue {
public:
stack<int> stIn;
stack<int> stOut;
MyQueue() {
}
void push(int x) {
stIn.push(x);
}
int pop() {
if (stOut.empty()) {
while (!stIn.empty()) {
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
int peek() {
int result = pop();
stOut.push(result);
return result;
}
bool empty() {
return stIn.empty() && stOut.empty();
}
};
C#
C#里Stack初始化要new,pop是有返回值的。
public class MyQueue {
Stack<int> inStack;
Stack<int> outStack;
public MyQueue() {
inStack = new Stack<int>();
outStack = new Stack<int>();
}
public void Push(int x) {
inStack.Push(x);
}
public int Pop() {
if (outStack.Count == 0) {
while (inStack.Count != 0) {
outStack.Push(inStack.Pop());
}
}
return outStack.Pop();
}
public int Peek() {
int result = Pop();
outStack.Push(result);
return result;
}
public bool Empty() {
return inStack.Count == 0 && outStack.Count == 0;
}
}
225. 用队列实现栈
可以两个队列也可以一个队列实现。
两个队列
需要一个额外队列来对数据进行备份,主队列在弹出的时候,要先把最后一个元素前面的所有元素存到备份队列里,再把最后一个元素弹出才是栈的方式,弹出完再把备份队列放回去。
C++
-
Top不用back也可以,调用一次Top,再把元素放回队列即可(见C#),注意整清楚操作的是队列,别像第一次整混了,画个图最好。
-
back进front出。
class MyStack {
public:
queue<int> que1;
queue<int> que2;
MyStack() {
}
void push(int x) {
que1.push(x);
}
int pop() {
int size = que1.size();
size--;
while(size--) {
que2.push(que1.front());
que1.pop();
}
int result = que1.front();
que1.pop();
que1 = que2;
while(!que2.empty()) {
que2.pop();
}
return result;
}
int top() {
return que1.back();
}
bool empty() {
return que1.empty();
}
};
C#
注意C#里队列是引用,不能直接=赋值,就一个东西了。
- 在 C++ 中,当两个对象使用“=”进行赋值时,会发生对象拷贝。也就是说,被赋值的对象会被拷贝一份,存储在另一个内存地址中。因此,在一般情况下,使用“=”进行赋值后,左右两边的对象是不同的对象,它们在内存中存储的位置也是不同的。但是,在某些特殊情况下,可以通过一些手段来使得赋值后左右两边的对象是同一个对象。其中一个常见的方法是使用指针或引用来进行赋值。
- 在 C# 中,赋值操作也会发生对象拷贝,不同的是,C# 中的赋值操作有值类型和引用类型之分。对于值类型,当使用“=”进行赋值时,会将右侧的值拷贝一份给左侧的变量,因此左右两边的变量是不同的对象,它们在内存中存储的位置也是不同的。对于引用类型,当使用“=”进行赋值时,会将右侧的引用拷贝一份给左侧的变量,因此左右两边的变量指向的是同一个对象,它们在内存中存储的位置也是同一个对象。
public class MyStack {
Queue<int> queue1;
Queue<int> queue2;
public MyStack() {
queue1 = new Queue<int>();
queue2 = new Queue<int>();
}
public void Push(int x) {
queue1.Enqueue(x);
}
public int Pop() {
int size = queue1.Count - 1;
while (size-- != 0) {
queue2.Enqueue(queue1.Dequeue());
}
int result = queue1.Dequeue();
while (queue2.Count != 0) {
queue1.Enqueue(queue2.Dequeue());
}
//Console.WriteLine(" 10 " + queue1.Peek());
//注意引用类型,queue1和queue2实际就是一个东西了
//Console.WriteLine(queue1.Peek());
return result;
}
public int Top() {
Console.WriteLine(queue1.Peek());
int result = Pop();
//还得放回去
Console.WriteLine(result);
queue1.Enqueue(result);
//Console.WriteLine(queue1.Peek());
return result;
}
public bool Empty() {
return queue1.Count == 0;
}
}
一个队列
C++
把size-1个元素取出再放入,就把最后面的元素放到了队列最前面,再弹出即可。
class MyStack {
public:
queue<int> que;
MyStack() {
}
void push(int x) {
que.push(x);
}
int pop() {
int size = que.size();
size--;
while (size--) {
int tmp = que.front();
que.pop();
que.push(tmp);
}
int result = que.front();
que.pop();
return result;
}
int top() {
int result = pop();
que.push(result);
return result;
}
bool empty() {
return que.empty();
}
};
C#
public class MyStack {
Queue<int> que = new Queue<int>();
public MyStack() {
}
public void Push(int x) {
que.Enqueue(x);
}
public int Pop() {
int size = que.Count;
size--;
while (size-- > 0) {
que.Enqueue(que.Dequeue());
}
return que.Dequeue();
}
public int Top() {
int result = Pop();
que.Enqueue(result);
return result;
}
public bool Empty() {
return que.Count == 0;
}
}
二刷
用栈实现队列
一个入栈,一个出栈,出栈的时候如果出栈为空,就把入站的全部放进来,否则就按现在弹出,从入栈到出栈的过程顺序就变成队列的顺序了。
#include<iostream>
#include<stack>
using namespace std;
class MyQueue {
public:
stack<int> inStack;
stack<int> outStack;
MyQueue() {
}
void push(int x) {
inStack.push(x);
}
int pop() {
if (outStack.empty()) {
while (!inStack.empty()) {
outStack.push(inStack.top());
inStack.pop();
}
}
int temp = outStack.top();
outStack.pop();
return temp;
}
int peek() {
if (outStack.empty()) {
while (!inStack.empty()) {
outStack.push(inStack.top());
inStack.pop();
}
}
return outStack.top();
}
bool empty() {
return inStack.empty() && outStack.empty();
}
};
用队列实现栈
一个队列就可以,每次push的时候把原来队列中的元素全部取出放到push元素的后面,就完成了顺序转换。
#include<iostream>
#include<queue>
using namespace std;
class MyStack {
public:
queue<int> qe;
MyStack() {
}
void push(int x) {
qe.push(x);
int cnt = qe.size() - 1;
while (cnt--) {
int temp = qe.front();
qe.pop();
qe.push(temp);
}
}
int pop() {
int temp = qe.front();
qe.pop();
return temp;
}
int top() {
return qe.front();
}
bool empty() {
return qe.empty();
}
};