- 使用两个栈模拟一个队列
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
typedef struct{
int *base;
int *top;
int stacksize;} stack;
int initStack(stack *s)//构造一个空栈
{
s->base = (int *)malloc(sizeof(int)*STACK_INIT_SIZE);
if(s->base == NULL)
{
printf("存储空间分配失败!");
exit(-1);
}
s->top = s->base;
s->stacksize = STACK_INIT_SIZE;
return 1;
}
//压栈的方法,i为需要压入栈顶的元素
int push(stack *s,int i)
{
//判断栈容量是否已经满了,如果已满,重新分配存储空间
if(s->top - s->base >= s->stacksize)
{
s->base = (int *)realloc(s->base,(s->stacksize + STACKINCREMENT)*sizeof(int));
}
if(s->base == NULL)
{
printf("内存分配失败!");
exit(-1);
}
*s->top++ = i; //把元素压栈
return 1;
}
//弹栈的方法
int pop(stack *s)
{
if(s->base == s->top)
return -1;
//本例中默认压入栈中的元素都是正整数,所以返回-1表示栈空
//如果栈不空,则删除栈顶元素并返回其值
return *--s->top;
}
//利用两个栈模拟一个队列
int main()
{
stack st1,st2;
initStack(&st1);
initStack(&st2);
//假设传入的队列为 1,2,3,4,5,6
//则出队列的时候顺序为 1,2,3,4,5,6
//先在栈1中压入这几个数
int i;
printf("进入队列的序列为:\n");
for(i = 1; i < 7 ;i++)
{
push(&st1,i);
printf("%d ",i);
}
printf("\n");
//出栈的时候每次先把1栈中除栈底元素之外的所有元素弹到2栈中
//然后再弹出1栈栈底元素
//最后再把2栈中的元素压入1栈中
//重复以上动作,直到1栈为空
printf("出队列的顺序为:\n");
while(st1.base!= st1.top)
{
while((st1.top - st1.base) > 1)
push(&st2,pop(&st1));
printf("%d ",pop(&st1));
while((st2.top - st2.base) > 0)
push(&st1,pop(&st2));
}
return 0;
}
-
用两个栈实现一个队列,实现队列的push和delete操作
栈的特性是先进后出(FILO),队列的特性是先进先出(FIFO),在实现delete时,我们的难点是如何将栈中最底层的数据拿出来,我们有两个栈,所以我们可以将一个栈中的数据依次拿出来压入到另一个为空的栈,另一个栈中数据的顺序恰好是先压入栈1的元素此时在栈2的上面,为了实现效率的提升,我们在delete时,判断栈2是否有数据,如果有的话,直接删除栈顶元素,在栈2为空时才将栈1的数据压入到栈2中,从而提高程序的运行效率,实现过程可以分为下面几个步骤:
1、push操作时,一直将数据压入到栈2中
2、delete操作时,首先判断栈2是否为空,不为空的情况直接删除栈2栈顶元素,为空的话将栈1的数据压入到栈2中,再将栈2栈顶元素删除。template <typename T> class CQueue { public: CQueue(void) {} ~CQueue(void) {} void appendTail(const T& node); T deleteHead(); private: stack<T> stack1; stack<T> stack2; }; template<class T> void CQueue<T>::appendTail(const T& node)//在队列尾部添加数据 { stack1.push(node); } template<class T> T CQueue<T>::deleteHead() { T tmp = 0; if (stack2.empty()) //若栈2为空 { while (!stack1.empty()) { tmp = stack1.top(); stack2.push(tmp); stack1.pop(); } } tmp = stack2.top(); stack2.pop(); return tmp; }
-
用两个队列实现一个栈
因为队列是先进先出,所以要拿到队列中最后压入的数据,只能每次将队列中数据pop到只剩一个,此时这个数据为最后压入队列的数据,在每次pop时,将数据压入到另一个队列中。每次执行delete操作时,循环往复。(感觉效率低)每次删除时间复杂度O(N)
template <typename T>
class CStack
{
public:
CStack(void)
{}
~CStack(void)
{}
void appendTail(const T& node);
T deleteHead();
private:
queue<T> q1;
queue<T> q2;
};
template<class T>
void CStack<T>::appendTail(const T& node)//在栈尾部添加数据
{
if (!q1.empty())//不为空的执行push操作
{
q1.push(node);
}
else
{
q2.push(node);
}
}
template<class T>
T CStack<T>::deleteHead()
{
int ret = 0;
if (q1.empty())
{
int i = q2.size();
while (i > 1 )//将q2队列中的数据pop到只剩一个
{
q1.push(q2.front());
q2.pop();
--i;
}
ret = q2.front();
q2.pop();
}
else
{
int i = q1.size();
while (i > 1)
{
q2.push(q1.front());
q1.pop();
--i;
}
ret = q1.front();
q1.pop();
}
return ret;