Algorithm 使用队列实现堆栈-最佳复杂性
我想知道是否有一种方法可以实现一个堆栈,根据需要使用尽可能多的队列来推送和弹出O(1)中的数据。Algorithm 使用队列实现堆栈-最佳复杂性,algorithm,stack,queue,time-complexity,Algorithm,Stack,Queue,Time Complexity,我想知道是否有一种方法可以实现一个堆栈,根据需要使用尽可能多的队列来推送和弹出O(1)中的数据。 如果没有任何O(1)算法,那么最好的复杂度是多少?您可以使用线性时间推送和恒定时间推送制作堆栈 给定一个具有函数ENQUEUE和DEQUEUE的队列: STACK: QUEUE q PUSH (S, x): r := new QUEUE ENQUEUE(r, x) while S.q not empty: v := DEQUEUE(S.q) ENQUEUE(r,
如果没有任何O(1)算法,那么最好的复杂度是多少?您可以使用线性时间推送和恒定时间推送制作堆栈 给定一个具有函数ENQUEUE和DEQUEUE的队列:
STACK:
QUEUE q
PUSH (S, x):
r := new QUEUE
ENQUEUE(r, x)
while S.q not empty:
v := DEQUEUE(S.q)
ENQUEUE(r, v)
S.q := r
POP (S):
RETURN DEQUEUE(S.q)
编辑:不需要临时队列管理器的替代解决方案:
STACK:
QUEUE q
PUSH (S, x):
ENQUEUE(S.q, x)
n := SIZE(S.q) - 1
repeat n times:
v := DEQUEUE(S.q)
ENQUEUE(S.q, v)
POP (S):
RETURN DEQUEUE(S.q)
您可以使用线性时间推送和固定时间弹出创建堆栈 给定一个具有函数ENQUEUE和DEQUEUE的队列:
STACK:
QUEUE q
PUSH (S, x):
r := new QUEUE
ENQUEUE(r, x)
while S.q not empty:
v := DEQUEUE(S.q)
ENQUEUE(r, v)
S.q := r
POP (S):
RETURN DEQUEUE(S.q)
编辑:不需要临时队列管理器的替代解决方案:
STACK:
QUEUE q
PUSH (S, x):
ENQUEUE(S.q, x)
n := SIZE(S.q) - 1
repeat n times:
v := DEQUEUE(S.q)
ENQUEUE(S.q, v)
POP (S):
RETURN DEQUEUE(S.q)
如果允许在队列中递归定义队列,则可以使用以下命令进行O(1)推送/弹出操作: 代码: 结果是一个递归形成的堆栈 如果
[1,2]
表示一个堆栈,其中出列([1,2])
将返回1
。然后将数据结构(如果1
然后3
然后6
推到堆栈上)如下所示:
[6,[3,[1,[]]]]
如果允许在队列中递归定义队列,则可以使用以下命令进行O(1)推送/弹出操作: 代码: 结果是一个递归形成的堆栈 如果
[1,2]
表示一个堆栈,其中出列([1,2])
将返回1
。然后将数据结构(如果1
然后3
然后6
推到堆栈上)如下所示:
[6,[3,[1,[]]]]
这里是一个用O(1)推和POP函数实现的堆栈的C++实现。 该接口类似于std::stack:
void push(const T& val);
void pop();
const T& top() const;
bool empty() const;
这是完整的代码。我想不出一种方法来避免混乱的类型转换
#include <iostream>
#include <stack>
#include <queue>
#include <stdexcept>
#define ASSERT(x) \
if (!(x)) { \
std::cout << "Assertion failed at line " << __LINE__ << "\n"; \
} \
template <typename T>
class Stack {
public:
Stack()
: m_head(NULL), m_tail(NULL) {}
void push(const T& val) {
std::queue<void*>* tail = new std::queue<void*>();
tail->push(reinterpret_cast<void*>(m_head));
tail->push(reinterpret_cast<void*>(m_tail));
m_head = new std::queue<T>();
m_head->push(val);
m_tail = tail;
}
void pop() {
if (m_head) {
delete m_head;
m_head = reinterpret_cast<std::queue<T>*>(m_tail->front());
m_tail->pop();
std::queue<void*>* tail = reinterpret_cast<std::queue<void*>*>(m_tail->front());
delete m_tail;
m_tail = tail;
}
}
const T& top() const {
if (!m_head) {
throw std::runtime_error("Error retrieving top element; stack empty");
}
return m_head->front();
}
bool empty() {
return !m_head;
}
private:
std::queue<T>* m_head;
std::queue<void*>* m_tail;
};
int main() {
Stack<int> s;
s.pop();
s.push(0);
ASSERT(s.top() == 0);
s.push(1);
ASSERT(s.top() == 1);
s.push(2);
ASSERT(s.top() == 2);
s.push(3);
ASSERT(s.top() == 3);
s.pop();
ASSERT(s.top() == 2)
s.push(4);
ASSERT(s.top() == 4);
s.push(5);
ASSERT(s.top() == 5);
s.push(6);
ASSERT(s.top() == 6);
s.pop();
ASSERT(s.top() == 5)
s.pop();
ASSERT(s.top() == 4)
s.push(7);
ASSERT(s.top() == 7);
s.pop();
ASSERT(s.top() == 4)
s.pop();
ASSERT(s.top() == 2)
s.pop();
ASSERT(s.top() == 1)
s.pop();
ASSERT(s.top() == 0)
s.pop();
ASSERT(s.empty())
s.pop();
int error = false;
try {
int x = s.top();
}
catch (std::exception&) {
error = true;
}
ASSERT(error == true);
return 0;
}
#包括
#包括
#包括
#包括
#定义断言(x)\
如果(!(x)){\
std::cout push(val);
m_tail=tail;
}
void pop(){
如果(m_头){
删除m_头;
m_head=重新解释(m_tail->front());
m_tail->pop();
std::queue*tail=reinterpret_cast(m_tail->front());
删除m_tail;
m_tail=tail;
}
}
常量T&top()常量{
如果(!m_头){
抛出std::runtime_错误(“检索顶部元素时出错;堆栈为空”);
}
返回m_head->front();
}
bool empty(){
回来!你的头;
}
私人:
std::队列*m_头;
std::queue*m_tail;
};
int main(){
堆栈s;
s、 pop();
s、 推(0);
断言(s.top()==0);
s、 推(1);
断言(s.top()==1);
s、 推(2);
断言(s.top()==2);
s、 推(3);
断言(s.top()==3);
s、 pop();
断言(s.top()==2)
s、 推(4);
断言(s.top()==4);
s、 推(5);
断言(s.top()==5);
s、 推(6);
断言(s.top()==6);
s、 pop();
断言(s.top()==5)
s、 pop();
断言(s.top()==4)
s、 推(7);
断言(s.top()==7);
s、 pop();
断言(s.top()==4)
s、 pop();
断言(s.top()==2)
s、 pop();
断言(s.top()==1)
s、 pop();
断言(s.top()==0)
s、 pop();
断言(s.empty())
s、 pop();
int error=false;
试一试{
int x=s.top();
}
捕获(标准::异常&){
错误=真;
}
断言(错误==true);
返回0;
}
> P>这里是一个用O(1)推和POP函数的堆栈的C++实现。
该接口类似于std::stack:
void push(const T& val);
void pop();
const T& top() const;
bool empty() const;
这是完整的代码。我想不出一种方法来避免混乱的类型转换
#include <iostream>
#include <stack>
#include <queue>
#include <stdexcept>
#define ASSERT(x) \
if (!(x)) { \
std::cout << "Assertion failed at line " << __LINE__ << "\n"; \
} \
template <typename T>
class Stack {
public:
Stack()
: m_head(NULL), m_tail(NULL) {}
void push(const T& val) {
std::queue<void*>* tail = new std::queue<void*>();
tail->push(reinterpret_cast<void*>(m_head));
tail->push(reinterpret_cast<void*>(m_tail));
m_head = new std::queue<T>();
m_head->push(val);
m_tail = tail;
}
void pop() {
if (m_head) {
delete m_head;
m_head = reinterpret_cast<std::queue<T>*>(m_tail->front());
m_tail->pop();
std::queue<void*>* tail = reinterpret_cast<std::queue<void*>*>(m_tail->front());
delete m_tail;
m_tail = tail;
}
}
const T& top() const {
if (!m_head) {
throw std::runtime_error("Error retrieving top element; stack empty");
}
return m_head->front();
}
bool empty() {
return !m_head;
}
private:
std::queue<T>* m_head;
std::queue<void*>* m_tail;
};
int main() {
Stack<int> s;
s.pop();
s.push(0);
ASSERT(s.top() == 0);
s.push(1);
ASSERT(s.top() == 1);
s.push(2);
ASSERT(s.top() == 2);
s.push(3);
ASSERT(s.top() == 3);
s.pop();
ASSERT(s.top() == 2)
s.push(4);
ASSERT(s.top() == 4);
s.push(5);
ASSERT(s.top() == 5);
s.push(6);
ASSERT(s.top() == 6);
s.pop();
ASSERT(s.top() == 5)
s.pop();
ASSERT(s.top() == 4)
s.push(7);
ASSERT(s.top() == 7);
s.pop();
ASSERT(s.top() == 4)
s.pop();
ASSERT(s.top() == 2)
s.pop();
ASSERT(s.top() == 1)
s.pop();
ASSERT(s.top() == 0)
s.pop();
ASSERT(s.empty())
s.pop();
int error = false;
try {
int x = s.top();
}
catch (std::exception&) {
error = true;
}
ASSERT(error == true);
return 0;
}
#包括
#包括
#包括
#包括
#定义断言(x)\
如果(!(x)){\
std::cout push(val);
m_tail=tail;
}
void pop(){
如果(m_头){
删除m_头;
m_head=重新解释(m_tail->front());
m_tail->pop();
std::queue*tail=reinterpret_cast(m_tail->front());
删除m_tail;
m_tail=tail;
}
}
常量T&top()常量{
如果(!m_头){
抛出std::runtime_错误(“检索顶部元素时出错;堆栈为空”);
}
返回m_head->front();
}
bool empty(){
回来!你的头;
}
私人:
std::队列*m_头;
std::queue*m_tail;
};
int main(){
堆栈s;
s、 pop();
s、 推(0);
断言(s.top()==0);
s、 推(1);
断言(s.top()==1);
s、 推(2);
断言(s.top()==2);
s、 推(3);
断言(s.top()==3);
s、 pop();
断言(s.top()==2)
s、 推(4);
断言(s.top()==4);
s、 推(5);
断言(s.top()==5);
s、 推(6);
断言(s.top()==6);
s、 pop();
断言(s.top()==5)
s、 pop();
断言(s.top()==4)
s、 推(7);
断言(s.top()==7);
s、 pop();
断言(s.top()==4)
s、 pop();
断言(s.top()==2)
s、 pop();
断言(s.top()==1)
s、 pop();
断言(s.top()==0)
s、 pop();
断言(s.empty())
s、 pop();
int error=false;
试一试{
int x=s.top();
}
捕获(标准::异常&){
错误=真;
}
断言(错误==true);
返回0;
}
你所说的O(1)是什么意思?我的意思是算法所花费的时间不应该依赖于n-堆栈的大小。它必须是恒定的算法做什么所花费的时间?我不这么认为。你为什么要这么做?直观地说,我倾向于说O(n)是最好的情况。如果你可以使用数组实现O(1)堆栈,你也可以使用一个由1个元素组成的队列数组,但那是毫无意义的。你能更好地定义这个问题吗?是否允许使用数组或变量,或者解决方案必须完全由队列组成?O(1)是什么意思?我的意思是,算法所花费的时间不应依赖于堆栈的大小。它必须是恒定的算法做什么所花费的时间?我不这么认为。你为什么要这么做?直观地说,我倾向于说O(n)是最好的情况。如果你可以使用数组实现O(1)堆栈,你也可以使用一个由1个元素组成的队列数组,但那是毫无意义的。你能更好地定义这个问题吗?您是否允许使用数组或变量,或者解决方案必须完全由队列组成。。是O(n)。但我无法想象有比这更好的了!谢谢你的回答:)好的。。是O(n)。但我无法想象