经典栈和队列相关面试题
1.实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1)
思路分析:
入栈:
将数据压入数据栈中,更新Min栈:data<=Min栈栈顶,data压入
Min栈
出栈:
检测data栈与Min栈栈顶的元素
代码如下:
typedef struct MinStack
{
Stack data;
Stack min;
}MinStack;
void MinStackInit(MinStack* ms);//初始化栈
void MinStackPush(MinStack* ms,SDataType data);//入栈
void MinStackPop(MinStack* ms);//出栈
SDataType MinStackTop(MinStack* ms);//栈顶元素
SDataType MinStackMin(MinStack* ms);//栈中最小元素
int MinStackSize(MinStack* ms);//栈中元素个数
int MinStackEmpty(MinStack* ms);//栈是否为空
//
//.c
void MinStackInit(MinStack* ms)
{
assert(ms);
StackInit(&(ms->data));
StackInit(&(ms->min));
}
void MinStackPush(MinStack* ms,SDataType data)
{
assert(ms);
if(StackEmpty(&(ms->min)) || StackTop(&(ms->min)) >= data)
{
StackPush(&(ms->min),data);
}
StackPush(&(ms->data),data);
}
void MinStackPop(MinStack* ms)
{
if(MinStackEmpty(ms))
return;
if(StackTop(&(ms->data)) == StackTop(&(ms->min)))
StackPop(&(ms->min));
StackPop(&(ms->data));
}
SDataType MinStackTop(MinStack* ms)
{
return StackTop(&(ms->data));
}
SDataType MinStackMin(MinStack* ms)
{
return StackTop(&(ms->min));
}
int MinStackSize(MinStack* ms)
{
return Stacksize(&(ms->data));
}
int MinStackEmpty(MinStack* ms)
{
return StackEmpty(&(ms->data));
}
2.使用两个队列实现一个栈
分析思路
压栈:
检测哪个队列有数据——>放数据到该队列中
出栈:
检测哪个队列有数据——>将队列中N-1个数据导入到另一个队列中,再出栈。
#include "Queue.h"
typedef struct StackBy2Queue
{
Queue _q1;
Queue _q2;
}StackBy2Queue;
void StackBy2QueueInit(StackBy2Queue *ps);//初始化
void StackBy2QueuePush(StackBy2Queue *ps,SDataType data);//压栈
void StackBy2QueuePop(StackBy2Queue* ps);//出栈
SDataType StackBy2QueueTop(StackBy2Queue *ps);//栈顶元素
int StackBy2Queuesize(StackBy2Queue *ps);//栈中元素个数
int StackBy2QueueEmpty(StackBy2Queue *ps);//是否为空
//.c
void StackBy2QueueInit(StackBy2Queue *ps)
{
QueueInit(&ps->_q1);
QueueInit(&ps->_q2);
}
void StackBy2QueuePush(StackBy2Queue *ps,SDataType data)
{
if(!QueueEmpty(&ps->_q1))
{
QueuePush(&ps->_q1,data);
}
else
QueuePush(&ps->_q2,data);
}
void StackBy2QueuePop(StackBy2Queue* ps)
{
if(!QueueEmpty(&ps->_q1))
{
while(QueueSize(&ps->_q1) > 1)
{
QueuePush(&ps->_q2,QueueFront(&ps->_q1));
QueuePop(&ps->_q1);
}
QueuePop(&ps->_q1);
}
else
{
while(QueueSize(&ps->_q2) > 1)
{
QueuePush(&ps->_q1,QueueFront(&ps->_q2));
QueuePop(&ps->_q2);
}
}
QueuePop(&ps->_q2);
}
SDataType StackBy2QueueTop(StackBy2Queue *ps)
{
if(!QueueEmpty(&ps->_q1))
return QueueBack(&ps->_q1);
else
return QueueBack(&ps->_q2);
}
int StackBy2Queuesize(StackBy2Queue *ps)
{
return QueueSize(&ps->_q1)+QueueSize(&ps->_q2);
}
int StackBy2QueueEmpty(StackBy2Queue *ps)
{
return QueueEmpty(&ps->_q1) && QueueEmpty(&ps->_q2);
}
3.使用两个栈实现一个队列
思路分析
入队列:数据放到栈1
出队列:检测栈2是否有数据 ,
有--->栈2出栈
没有--->将栈1中数据导入到栈2
取队头元素—–>栈2栈顶元素
取队尾元素—–>栈1栈顶
有----->取栈1栈顶元素,直接返回
没有----->将栈2中元素导入到栈1
typedef struct QueueBy2Stack
{
Stack s1;
Stack s2;
}QueueBy2Stack;
void QueueBy2StackInit(QueueBy2Stack* q);
void QueueBy2StackPush(QueueBy2Stack* q,SDataType data);
void QueueBy2StackPop(QueueBy2Stack* q);
int QueueBy2StackSize(QueueBy2Stack *q);
int QueueBy2StackEmpty(QueueBy2Stack* q);
SDataType Front(QueueBy2Stack *q);
SDataType Back(QueueBy2Stack *q);
///
//.c
#include<assert.h>
void QueueBy2StackInit(QueueBy2Stack* q)
{
assert(q);
StackInit(&q->s1);
StackInit(&q->s2);
}
void QueueBy2StackPush(QueueBy2Stack* q,SDataType data)
{
assert(q);
StackPush(&q->s1,data);
}
void QueueBy2StackPop(QueueBy2Stack* q)
{
assert(q);
if(QueueBy2StackEmpty(q))
return;
if(StackEmpty(&q->s2))
{
while(!StackEmpty(&q->s1))
{
StackPush(&q->s2,StackTop(&q->s1));
StackPop(&q->s1);
}
}
StackPop(&q->s2);
}
int QueueBy2StackSize(QueueBy2Stack *q)
{
assert(q);
return Stacksize(&(q->s1) + Stacksize(&q->s2));
}
int QueueBy2StackEmpty(QueueBy2Stack* q)
{
assert(q);
return StackEmpty(&q->s1) && StackEmpty(&q->s2);
}
SDataType QueueBy2StackFront(QueueBy2Stack *q)
{
assert(!(QueueBy2StackEmpty(q)));
if(StackEmpty(&q->s2))
{
while(!StackEmpty(&q->s1))
{
StackPush(&q->s2,StackTop(&q->s1));
StackPop(&q->s1);
}
}
return StackTop(&q->s2);
}
SDataType QueueBy2StackBack(QueueBy2Stack *q)
{
assert(!(QueueBy2StackEmpty(q)));
if(StackEmpty(&q->s1))
{
while(!StackEmpty(&q->s2))
{
StackPush(&q->s1,StackTop(&q->s2));
StackPop(&q->s2);
}
}
return StackTop(&q->s1);
}
4.元素入栈、出栈顺序的合法性。
思路分析
int IsStackValidOrder(int * InArr,int InSize,int * outArr,int outSize)
{
Stack s;
int InIdx = 0;
int outIdx = 0;
//入栈与出栈元素个数不同
if(InSize != outSize)
return 0;
//入栈与出栈元素个数相同
StackInit(&s);
while(outIdx<outSize)
{
while(StackEmpty(&s)|| StackTop(&s)!=outArr[outIdx])
{
if(InIdx<InSize)
StackPush(&s,InArr[InIdx++]);
else
{
printf("入栈与出栈元素次序不匹配!\n");
return 0 ;
}
}
StackPop(&s);
outIdx++;
//栈空-->次序已匹配 outIdx == outSize
// -->出栈outIdx没有到边界
}
printf("入栈与出栈元素次序合法!\n");
return 1;
}
5.一个数组实现两个栈(共享栈)
typedef struct SharedStack
{
SDataType arry[MAXSIZE];
int top1;
int top2;
}SharedStack;
void SharedStackInit(SharedStack *ps);
void SharedStackPush(SharedStack *ps,SDataType data,int which);
void SharedStackPop(SharedStack* ps,int which);
SDataType SharedStackTop(SharedStack *ps,int which);
int SharedStacksize(SharedStack *ps,int which);
int SharedStackEmpty(SharedStack *ps,int which);
////////////////////////////////////////////////////////////
//.c
void SharedStackInit(SharedStack *ps)
{
assert(ps);
ps->top1 = 0;
ps->top2 = MAXSIZE-1;
}
void SharedStackPush(SharedStack *ps,SDataType data,int which)
{
if(ps->top1>ps->top2)
return;
if(which == 1)
ps->arry[ps->top1++] = data;
else
ps->arry[ps->top2--] = data;
}
void SharedStackPop(SharedStack* ps,int which)
{
assert(ps);
if(1 == which)
{
if(ps->top1 > 0)
ps->top1--;
}
else
{
if(ps->top2 < MAXSIZE-1)
ps->top2++;
}
}
SDataType SharedStackTop(SharedStack *ps,int which)
{
assert(ps);
if(which ==1)
return ps->arry[ps->top1-1];
else
return ps->arry[ps->top2+1];
}
int SharedStacksize(SharedStack *ps,int which)
{
assert(ps);
if(1==which)
return ps->top1;
else
return MAXSIZE - ps->top2-1;
}
int SharedStackEmpty(SharedStack *ps,int which)
{
if(1 == which)
return 0 == SharedStacksize(ps,which);
}