面试题七:用两个栈实现队列
题目:
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail, deleteHead,分别完成在队列尾部插入结点和在队列头部插入结点删除结点的功能;
分析:栈的特性---“先进后出”,队列的特性---“先进先出”,所以这道题的入口点就是这两个数据结构的特性。
我们可以这样,先创建两个栈stack1和stack2,当有数据来的时候,我们都放在stack1中(入队),如果想要出数据的话(出队),我们可以利用stack2,前提是stack2为空,我们把stack1的数据全部进行出栈,每出栈一个,把出栈的这个数据压入stack2中,直到stack1为空为止,这时候stack2的栈顶就是我们队列的队头了,然后进行相应的出栈,也就是模拟队列的出队操作,这样就实现了我们所谓的利用两个栈模拟队列的功能实现了。
详细图解:
代码中用到的栈类和链表类在《剑指offer》【面试题5:从尾到头打印链表】中曾实现;
面试题七:代码实现
//面试题七:
//队列尾部插入:
void appendTail(CDstack *stack1,CDstack *stack2,int val)
{
assert(stack1 != NULL && stack2!= NULL);
stack1->push(val);//每次插入到栈一中
}
//队列头部删除:
int deleteHead(CDstack *stack1,CDstack *stack2,int *retval)
{
assert(stack1 != NULL && stack2 != NULL);
if (stack2->isempty())
{
while(!stack1->isempty())
{
int val;
stack1->pop(&val);
stack2->push(val);
}
}
stack2->pop(retval);//每次通过栈2弹出
return *retval;
}
int main()
{
//---------------------------- 面试题七的测试用例-------------------------------------
CDstack stack1;
CDstack stack2;
for (int i = 0; i<10; i++)
{
appendTail(&stack1,&stack2,i);//循环插入到栈一中
}
cout<<"入队的值"<<endl;
stack1.show();
int retval;
cout<<"出队的值 "<<endl;
cout<<deleteHead(&stack1,&stack2,&retval)<<" ";//第一次弹出的值
cout<<endl;
cout<<"队中剩下的值"<<endl;
stack2.show();//栈2中剩下的值
}